From e1ed5fc21916a6ca9d692736e86d0d64e2d1a9df Mon Sep 17 00:00:00 2001 From: George Sokianos Date: Mon, 27 Dec 2021 19:14:31 +0000 Subject: [PATCH] Initial commit with agg r138 svn files --- AUTHORS | 2 + CMakeLists.txt | 244 + ChangeLog | 1 + Makefile | 9 + Makefile.AmigaOS | 398 + Makefile.am | 21 + Makefile.in.BeOS | 7 + Makefile.in.CYGWIN_NT-5.0 | 8 + Makefile.in.CYGWIN_NT-5.1 | 8 + Makefile.in.Darwin | 8 + Makefile.in.Darwin.SDL | 8 + Makefile.in.IRIX64 | 7 + Makefile.in.Linux | 8 + Makefile.in.Linux.SDL | 8 + Makefile.in.MINGW32_NT-5.0 | 8 + Makefile.in.MINGW32_NT-5.1 | 8 + Makefile.in.SunOS | 7 + NEWS | 1 + README | 63 + agg2d/agg2d.cpp | 1837 +++ agg2d/agg2d.h | 599 + autogen.sh | 23 + bin/AggConfig.cmake.in | 36 + bin/AggConfigOutBuild.cmake.in | 37 + bin/FindAgg.cmake | 157 + bin/FindEXPAT.cmake | 38 + bin/FindFreetype.cmake | 98 + bin/UseAgg.cmake.in | 34 + cmake_install.html | 234 + configure.ac | 166 + copying | 65 + distclean | 24 + doc/AggCP-Gradients1_readme.txt | 85 + examples/BeOS/Makefile | 391 + examples/BeOS/readme.txt | 36 + examples/CMakeLists.txt | 331 + examples/Makefile.am | 248 + examples/X11/Makefile | 340 + examples/X11/readme.txt | 36 + examples/aa_demo.cpp | 290 + examples/aa_test.cpp | 581 + examples/agg2d_demo.cpp | 419 + examples/alpha_gradient.cpp | 373 + examples/alpha_mask.cpp | 203 + examples/alpha_mask2.cpp | 419 + examples/alpha_mask3.cpp | 569 + examples/art/1.sdf | 2825 ++++ examples/art/agg.bmp | Bin 0 -> 3126 bytes examples/art/agg.ppm | Bin 0 -> 3108 bytes examples/art/compositing.bmp | Bin 0 -> 64118 bytes examples/art/compositing.ppm | 101 + examples/art/line_patterns.bmp.zip | Bin 0 -> 8548 bytes examples/art/line_patterns.tar.gz | Bin 0 -> 6276 bytes examples/art/shapes.txt | 10740 ++++++++++++++++ examples/art/spheres.bmp | Bin 0 -> 288054 bytes examples/art/spheres.ppm | Bin 0 -> 288015 bytes examples/art/tiger.svg | 728 ++ examples/art/timesi.zip | Bin 0 -> 152912 bytes examples/bezier_div.cpp | 572 + examples/blend_color.cpp | 555 + examples/blur.cpp | 327 + examples/bspline.cpp | 207 + examples/circles.cpp | 268 + examples/component_rendering.cpp | 93 + examples/compositing.cpp | 374 + examples/compositing2.cpp | 251 + examples/conv_contour.cpp | 164 + examples/conv_dash_marker.cpp | 286 + examples/conv_stroke.cpp | 276 + examples/distortions.cpp | 709 + examples/flash_rasterizer.cpp | 561 + examples/flash_rasterizer2.cpp | 535 + examples/freetype_test.cpp | 484 + examples/gamma_correction.cpp | 178 + examples/gamma_ctrl.cpp | 251 + examples/gamma_tuner.cpp | 236 + examples/gouraud.cpp | 314 + examples/gouraud_mesh.cpp | 485 + examples/gpc_test.cpp | 685 + examples/gradient_focal.cpp | 252 + examples/gradients.cpp | 531 + examples/gradients_contour.cpp | 1797 +++ examples/graph_test.cpp | 925 ++ examples/idea.cpp | 364 + examples/image1.cpp | 214 + examples/image_alpha.cpp | 251 + examples/image_filters.cpp | 428 + examples/image_filters2.cpp | 273 + examples/image_fltr_graph.cpp | 315 + examples/image_perspective.cpp | 329 + examples/image_resample.cpp | 371 + examples/image_transforms.cpp | 454 + examples/interactive_polygon.cpp | 284 + examples/interactive_polygon.h | 111 + examples/line_patterns.cpp | 334 + examples/line_patterns_clip.cpp | 353 + examples/line_thickness.cpp | 145 + examples/lion.cpp | 175 + examples/lion_lens.cpp | 204 + examples/lion_outline.cpp | 192 + examples/macosx_carbon/Makefile | 280 + examples/macosx_carbon/readme.txt | 24 + examples/macosx_sdl/Makefile | 358 + examples/macosx_sdl/readme.txt | 36 + examples/make_arrows.cpp | 43 + examples/make_gb_poly.cpp | 1894 +++ examples/mol_view.cpp | 1076 ++ examples/multi_clip.cpp | 374 + examples/parse_lion.cpp | 215 + examples/pattern_fill.cpp | 382 + examples/pattern_perspective.cpp | 297 + examples/pattern_resample.cpp | 399 + examples/perspective.cpp | 311 + examples/pixel_formats.h | 344 + examples/polymorphic_renderer.cpp | 167 + examples/raster_text.cpp | 179 + examples/rasterizer_compound.cpp | 273 + examples/rasterizers.cpp | 281 + examples/rasterizers2.cpp | 552 + examples/rounded_rect.cpp | 161 + examples/scanline_boolean.cpp | 281 + examples/scanline_boolean2.cpp | 675 + examples/simple_blur.cpp | 260 + examples/svg_viewer/agg_svg_exception.h | 69 + examples/svg_viewer/agg_svg_parser.cpp | 953 ++ examples/svg_viewer/agg_svg_parser.h | 87 + examples/svg_viewer/agg_svg_path_renderer.cpp | 403 + examples/svg_viewer/agg_svg_path_renderer.h | 327 + .../svg_viewer/agg_svg_path_tokenizer.cpp | 144 + examples/svg_viewer/agg_svg_path_tokenizer.h | 114 + examples/svg_viewer/svg_test.cpp | 261 + examples/trans_curve1.cpp | 327 + examples/trans_curve1_ft.cpp | 327 + examples/trans_curve2.cpp | 394 + examples/trans_curve2_ft.cpp | 391 + examples/trans_polar.cpp | 202 + examples/truetype_test.cpp | 450 + examples/win32_api/Makefile | 107 + examples/win32_api/aa_demo/Makefile | 39 + examples/win32_api/aa_demo/aa_demo.dsp | 139 + examples/win32_api/aa_demo/aa_demo.dsw | 29 + examples/win32_api/aa_demo/aa_demo.vcxproj | 144 + examples/win32_api/aa_test/Makefile | 40 + examples/win32_api/aa_test/aa_test.dsp | 143 + examples/win32_api/aa_test/aa_test.dsw | 29 + examples/win32_api/aa_test/aa_test.vcxproj | 156 + examples/win32_api/agg.props | 12 + examples/win32_api/agg2d_demo/Makefile | 46 + .../win32_api/agg2d_demo/agg2d_demo.vcxproj | 86 + examples/win32_api/alpha_gradient/Makefile | 40 + .../alpha_gradient/alpha_gradient.dsp | 151 + .../alpha_gradient/alpha_gradient.dsw | 29 + .../alpha_gradient/alpha_gradient.vcxproj | 160 + examples/win32_api/alpha_mask/Makefile | 41 + examples/win32_api/alpha_mask/alpha_mask.dsp | 139 + examples/win32_api/alpha_mask/alpha_mask.dsw | 29 + .../win32_api/alpha_mask/alpha_mask.vcxproj | 157 + examples/win32_api/alpha_mask2/Makefile | 41 + .../win32_api/alpha_mask2/alpha_mask2.dsp | 155 + .../win32_api/alpha_mask2/alpha_mask2.dsw | 29 + .../win32_api/alpha_mask2/alpha_mask2.vcxproj | 163 + examples/win32_api/alpha_mask3/Makefile | 42 + .../win32_api/alpha_mask3/alpha_mask3.dsp | 155 + .../win32_api/alpha_mask3/alpha_mask3.dsw | 29 + .../win32_api/alpha_mask3/alpha_mask3.vcxproj | 159 + examples/win32_api/bezier_div/Makefile | 42 + examples/win32_api/bezier_div/bezier_div.dsp | 175 + examples/win32_api/bezier_div/bezier_div.dsw | 29 + .../win32_api/bezier_div/bezier_div.vcxproj | 164 + examples/win32_api/blend_color/Makefile | 40 + .../win32_api/blend_color/blend_color.dsp | 163 + .../win32_api/blend_color/blend_color.dsw | 29 + .../win32_api/blend_color/blend_color.vcxproj | 161 + examples/win32_api/blur/Makefile | 40 + examples/win32_api/blur/blur.dsp | 163 + examples/win32_api/blur/blur.dsw | 29 + examples/win32_api/blur/blur.vcxproj | 161 + examples/win32_api/bspline/Makefile | 42 + examples/win32_api/bspline/bspline.dsp | 151 + examples/win32_api/bspline/bspline.dsw | 29 + examples/win32_api/bspline/bspline.vcxproj | 160 + examples/win32_api/circles/Makefile | 40 + examples/win32_api/circles/circles.dsp | 157 + examples/win32_api/circles/circles.dsw | 29 + examples/win32_api/circles/circles.vcxproj | 161 + .../win32_api/component_rendering/Makefile | 40 + .../component_rendering.dsp | 137 + .../component_rendering.dsw | 29 + .../component_rendering.vcxproj | 156 + examples/win32_api/compositing/Makefile | 39 + .../win32_api/compositing/compositing.dsp | 159 + .../win32_api/compositing/compositing.dsw | 29 + .../win32_api/compositing/compositing.vcxproj | 162 + examples/win32_api/compositing/readme | 1 + examples/win32_api/compositing2/Makefile | 39 + .../win32_api/compositing2/compositing2.dsp | 163 + .../win32_api/compositing2/compositing2.dsw | 29 + .../compositing2/compositing2.vcxproj | 163 + examples/win32_api/conv_contour/Makefile | 40 + .../win32_api/conv_contour/conv_contour.dsp | 159 + .../win32_api/conv_contour/conv_contour.dsw | 29 + .../conv_contour/conv_contour.vcxproj | 160 + examples/win32_api/conv_dash_marker/Makefile | 40 + .../conv_dash_marker/conv_dash_marker.dsp | 175 + .../conv_dash_marker/conv_dash_marker.dsw | 29 + .../conv_dash_marker/conv_dash_marker.vcxproj | 164 + examples/win32_api/conv_stroke/Makefile | 40 + .../win32_api/conv_stroke/conv_stroke.dsp | 171 + .../win32_api/conv_stroke/conv_stroke.dsw | 29 + .../win32_api/conv_stroke/conv_stroke.vcxproj | 163 + examples/win32_api/distortions/Makefile | 40 + .../win32_api/distortions/distortions.dsp | 161 + .../win32_api/distortions/distortions.dsw | 29 + .../win32_api/distortions/distortions.vcxproj | 164 + examples/win32_api/distortions/readme | 5 + examples/win32_api/examples.dsw | 761 ++ examples/win32_api/examples.sln | 744 ++ examples/win32_api/flash_rasterizer/Makefile | 40 + .../flash_rasterizer/flash_rasterizer.dsp | 147 + .../flash_rasterizer/flash_rasterizer.dsw | 29 + .../flash_rasterizer/flash_rasterizer.vcxproj | 159 + examples/win32_api/flash_rasterizer2/Makefile | 40 + .../flash_rasterizer2/flash_rasterizer2.dsp | 143 + .../flash_rasterizer2/flash_rasterizer2.dsw | 29 + .../flash_rasterizer2.vcxproj | 156 + examples/win32_api/freetype_test/Makefile | 42 + .../win32_api/freetype_test/freetype_test.dsp | 159 + .../win32_api/freetype_test/freetype_test.dsw | 29 + .../freetype_test/freetype_test.vcxproj | 160 + examples/win32_api/freetype_test/readme | 9 + examples/win32_api/gamma_correction/Makefile | 40 + .../gamma_correction/gamma_correction.dsp | 135 + .../gamma_correction/gamma_correction.dsw | 29 + .../gamma_correction/gamma_correction.vcxproj | 154 + examples/win32_api/gamma_ctrl/Makefile | 39 + examples/win32_api/gamma_ctrl/gamma_ctrl.dsp | 145 + examples/win32_api/gamma_ctrl/gamma_ctrl.dsw | 29 + .../win32_api/gamma_ctrl/gamma_ctrl.vcxproj | 158 + examples/win32_api/gamma_tuner/Makefile | 39 + .../win32_api/gamma_tuner/gamma_tuner.dsp | 139 + .../win32_api/gamma_tuner/gamma_tuner.dsw | 29 + .../win32_api/gamma_tuner/gamma_tuner.vcxproj | 155 + examples/win32_api/gouraud/Makefile | 40 + examples/win32_api/gouraud/gouraud.dsp | 135 + examples/win32_api/gouraud/gouraud.dsw | 29 + examples/win32_api/gouraud/gouraud.vcxproj | 154 + examples/win32_api/gouraud_mesh/Makefile | 40 + .../win32_api/gouraud_mesh/gouraud_mesh.dsp | 155 + .../win32_api/gouraud_mesh/gouraud_mesh.dsw | 29 + .../gouraud_mesh/gouraud_mesh.vcxproj | 184 + examples/win32_api/gpc_test/Makefile | 42 + examples/win32_api/gpc_test/gpc_test.dsp | 159 + examples/win32_api/gpc_test/gpc_test.dsw | 29 + examples/win32_api/gpc_test/gpc_test.vcxproj | 160 + examples/win32_api/gradient_focal/Makefile | 38 + .../gradient_focal/gradient_focal.dsp | 163 + .../gradient_focal/gradient_focal.dsw | 29 + .../gradient_focal/gradient_focal.vcxproj | 165 + examples/win32_api/gradients/Makefile | 40 + examples/win32_api/gradients/gradients.dsp | 165 + examples/win32_api/gradients/gradients.dsw | 29 + .../win32_api/gradients/gradients.vcxproj | 161 + examples/win32_api/gradients/settings.dat | 56 + examples/win32_api/graph_test/Makefile | 40 + examples/win32_api/graph_test/graph_test.dsp | 180 + examples/win32_api/graph_test/graph_test.dsw | 29 + .../win32_api/graph_test/graph_test.vcxproj | 165 + examples/win32_api/idea/Makefile | 40 + examples/win32_api/idea/idea.dsp | 141 + examples/win32_api/idea/idea.dsw | 29 + examples/win32_api/idea/idea.vcxproj | 157 + examples/win32_api/image1/Makefile | 40 + examples/win32_api/image1/image1.dsp | 153 + examples/win32_api/image1/image1.dsw | 29 + examples/win32_api/image1/image1.vcxproj | 160 + examples/win32_api/image1/readme | 1 + examples/win32_api/image_alpha/Makefile | 40 + .../win32_api/image_alpha/image_alpha.dsp | 149 + .../win32_api/image_alpha/image_alpha.dsw | 29 + .../win32_api/image_alpha/image_alpha.vcxproj | 159 + examples/win32_api/image_alpha/readme | 1 + examples/win32_api/image_filters/Makefile | 40 + .../win32_api/image_filters/image_filters.dsp | 173 + .../win32_api/image_filters/image_filters.dsw | 29 + .../image_filters/image_filters.vcxproj | 167 + examples/win32_api/image_filters/readme | 1 + examples/win32_api/image_filters2/Makefile | 40 + .../image_filters2/image_filters2.dsp | 161 + .../image_filters2/image_filters2.dsw | 29 + .../image_filters2/image_filters2.vcxproj | 162 + examples/win32_api/image_filters2/readme | 1 + examples/win32_api/image_fltr_graph/Makefile | 40 + .../image_fltr_graph/image_fltr_graph.dsp | 169 + .../image_fltr_graph/image_fltr_graph.dsw | 29 + .../image_fltr_graph/image_fltr_graph.vcxproj | 166 + examples/win32_api/image_perspective/Makefile | 42 + .../image_perspective/image_perspective.dsp | 151 + .../image_perspective/image_perspective.dsw | 29 + .../image_perspective.vcxproj | 162 + examples/win32_api/image_perspective/readme | 1 + examples/win32_api/image_resample/Makefile | 42 + .../image_resample/image_resample.dsp | 187 + .../image_resample/image_resample.dsw | 29 + .../image_resample/image_resample.vcxproj | 171 + examples/win32_api/image_resample/readme | 1 + examples/win32_api/image_transforms/Makefile | 40 + .../image_transforms/image_transforms.dsp | 173 + .../image_transforms/image_transforms.dsw | 29 + .../image_transforms/image_transforms.vcxproj | 167 + examples/win32_api/image_transforms/readme! | 189 + examples/win32_api/line_patterns/Makefile | 40 + .../win32_api/line_patterns/line_patterns.dsp | 163 + .../win32_api/line_patterns/line_patterns.dsw | 29 + .../line_patterns/line_patterns.vcxproj | 161 + .../win32_api/line_patterns_clip/Makefile | 40 + .../line_patterns_clip/line_patterns_clip.dsp | 167 + .../line_patterns_clip/line_patterns_clip.dsw | 29 + .../line_patterns_clip.vcxproj | 162 + .../line_thickness/line_thickness.vcxproj | 199 + examples/win32_api/lion/Makefile | 41 + examples/win32_api/lion/lion.dsp | 143 + examples/win32_api/lion/lion.dsw | 29 + examples/win32_api/lion/lion.vcxproj | 160 + examples/win32_api/lion_lens/Makefile | 41 + examples/win32_api/lion_lens/lion_lens.dsp | 147 + examples/win32_api/lion_lens/lion_lens.dsw | 29 + .../win32_api/lion_lens/lion_lens.vcxproj | 159 + examples/win32_api/lion_outline/Makefile | 41 + .../win32_api/lion_outline/lion_outline.dsp | 155 + .../win32_api/lion_outline/lion_outline.dsw | 29 + .../lion_outline/lion_outline.vcxproj | 161 + examples/win32_api/mol_view/Makefile | 40 + examples/win32_api/mol_view/mol_view.dsp | 177 + examples/win32_api/mol_view/mol_view.dsw | 29 + examples/win32_api/mol_view/mol_view.vcxproj | 166 + examples/win32_api/mol_view/readme | 2 + examples/win32_api/multi_clip/Makefile | 41 + examples/win32_api/multi_clip/multi_clip.dsp | 151 + examples/win32_api/multi_clip/multi_clip.dsw | 29 + .../win32_api/multi_clip/multi_clip.vcxproj | 160 + examples/win32_api/pattern_fill/Makefile | 40 + .../win32_api/pattern_fill/pattern_fill.dsp | 169 + .../win32_api/pattern_fill/pattern_fill.dsw | 29 + .../pattern_fill/pattern_fill.vcxproj | 166 + .../pattern_perspective.dsp | 171 + .../pattern_perspective.dsw | 29 + .../pattern_perspective.vcxproj | 167 + examples/win32_api/pattern_resample/Makefile | 42 + .../pattern_resample/pattern_resample.dsp | 179 + .../pattern_resample/pattern_resample.dsw | 29 + .../pattern_resample/pattern_resample.vcxproj | 169 + examples/win32_api/perspective/Makefile | 42 + .../win32_api/perspective/perspective.dsp | 143 + .../win32_api/perspective/perspective.dsw | 29 + .../win32_api/perspective/perspective.vcxproj | 158 + .../win32_api/polymorphic_renderer/Makefile | 40 + .../polymorphic_renderer.dsp | 131 + .../polymorphic_renderer.dsw | 29 + .../polymorphic_renderer.vcxproj | 153 + examples/win32_api/pure_api/StdAfx.cpp | 8 + examples/win32_api/pure_api/StdAfx.h | 32 + examples/win32_api/pure_api/pure_api.cpp | 292 + examples/win32_api/pure_api/pure_api.dsp | 137 + examples/win32_api/pure_api/pure_api.dsw | 29 + examples/win32_api/pure_api/pure_api.h | 12 + examples/win32_api/pure_api/pure_api.ico | Bin 0 -> 1078 bytes examples/win32_api/pure_api/pure_api.rc | 135 + examples/win32_api/pure_api/pure_api.vcxproj | 161 + examples/win32_api/pure_api/resource.h | 27 + examples/win32_api/pure_api/small.ico | Bin 0 -> 318 bytes examples/win32_api/raster_text/Makefile | 40 + .../win32_api/raster_text/raster_text.dsp | 151 + .../win32_api/raster_text/raster_text.dsw | 29 + .../win32_api/raster_text/raster_text.vcxproj | 160 + .../win32_api/rasterizer_compound/Makefile | 40 + .../rasterizer_compound.dsp | 159 + .../rasterizer_compound.dsw | 29 + .../rasterizer_compound.vcxproj | 160 + examples/win32_api/rasterizers/Makefile | 40 + .../win32_api/rasterizers/rasterizers.dsp | 151 + .../win32_api/rasterizers/rasterizers.dsw | 29 + .../win32_api/rasterizers/rasterizers.vcxproj | 158 + examples/win32_api/rasterizers2/Makefile | 40 + .../win32_api/rasterizers2/rasterizers2.dsp | 199 + .../win32_api/rasterizers2/rasterizers2.dsw | 29 + .../rasterizers2/rasterizers2.vcxproj | 172 + examples/win32_api/rounded_rect/Makefile | 40 + .../win32_api/rounded_rect/rounded_rect.dsp | 147 + .../win32_api/rounded_rect/rounded_rect.dsw | 29 + .../rounded_rect/rounded_rect.vcxproj | 157 + examples/win32_api/scanline_boolean/Makefile | 42 + .../scanline_boolean/scanline_boolean.dsp | 151 + .../scanline_boolean/scanline_boolean.dsw | 29 + .../scanline_boolean/scanline_boolean.vcxproj | 162 + examples/win32_api/scanline_boolean2/Makefile | 42 + .../scanline_boolean2/scanline_boolean2.dsp | 155 + .../scanline_boolean2/scanline_boolean2.dsw | 29 + .../scanline_boolean2.vcxproj | 159 + examples/win32_api/simple_blur/Makefile | 41 + .../win32_api/simple_blur/simple_blur.dsp | 151 + .../win32_api/simple_blur/simple_blur.dsw | 29 + .../win32_api/simple_blur/simple_blur.vcxproj | 160 + examples/win32_api/svg_test/svg_test.dsp | 172 + examples/win32_api/svg_test/svg_test.dsw | 29 + examples/win32_api/svg_test/svg_test.vcxproj | 169 + examples/win32_api/trans_curve1/Makefile | 46 + .../win32_api/trans_curve1/trans_curve1.dsp | 167 + .../win32_api/trans_curve1/trans_curve1.dsw | 29 + .../trans_curve1/trans_curve1.vcxproj | 164 + examples/win32_api/trans_curve2/Makefile | 46 + .../win32_api/trans_curve2/trans_curve2.dsp | 171 + .../win32_api/trans_curve2/trans_curve2.dsw | 29 + .../trans_curve2/trans_curve2.vcxproj | 167 + examples/win32_api/trans_polar/Makefile | 40 + .../win32_api/trans_polar/trans_polar.dsp | 143 + .../win32_api/trans_polar/trans_polar.dsw | 29 + .../win32_api/trans_polar/trans_polar.vcxproj | 156 + examples/win32_api/truetype_test/Makefile | 45 + .../win32_api/truetype_test/truetype_test.dsp | 155 + .../win32_api/truetype_test/truetype_test.dsw | 29 + .../truetype_test/truetype_test.vcxproj | 159 + examples/win32_api_dmc/Makefile | 593 + examples/win32_api_dmc/readme | 20 + font_freetype/Makefile.am | 11 + font_freetype/agg_font_freetype.cpp | 1149 ++ font_freetype/agg_font_freetype.h | 196 + font_freetype/agg_font_freetype2.cpp | 877 ++ font_freetype/agg_font_freetype2.h | 331 + font_win32_tt/Makefile.am | 13 + font_win32_tt/agg_font_win32_tt.cpp | 938 ++ font_win32_tt/agg_font_win32_tt.h | 214 + gpc/Makefile.am | 11 + gpc/VERSIONS.TXT | 123 + gpc/copying.txt | 22 + gpc/gpc.c | 2472 ++++ gpc/gpc.h | 133 + include/Makefile.am | 49 + include/agg_alpha_mask_u8.h | 499 + include/agg_arc.h | 73 + include/agg_array.h | 1119 ++ include/agg_arrowhead.h | 82 + include/agg_basics.h | 574 + include/agg_bezier_arc.h | 159 + include/agg_bitset_iterator.h | 54 + include/agg_blur.h | 1505 +++ include/agg_bounding_rect.h | 116 + include/agg_bspline.h | 76 + include/agg_clip_liang_barsky.h | 333 + include/agg_color_gray.h | 1047 ++ include/agg_color_rgba.h | 1353 ++ include/agg_config.h | 44 + include/agg_conv_adaptor_vcgen.h | 157 + include/agg_conv_adaptor_vpgen.h | 159 + include/agg_conv_bspline.h | 48 + include/agg_conv_clip_polygon.h | 63 + include/agg_conv_clip_polyline.h | 63 + include/agg_conv_close_polygon.h | 125 + include/agg_conv_concat.h | 73 + include/agg_conv_contour.h | 65 + include/agg_conv_curve.h | 201 + include/agg_conv_dash.h | 68 + include/agg_conv_gpc.h | 432 + include/agg_conv_marker.h | 149 + include/agg_conv_marker_adaptor.h | 51 + include/agg_conv_segmentator.h | 48 + include/agg_conv_shorten_path.h | 50 + include/agg_conv_smooth_poly1.h | 80 + include/agg_conv_stroke.h | 73 + include/agg_conv_transform.h | 68 + include/agg_conv_unclose_polygon.h | 52 + include/agg_curves.h | 695 + include/agg_dda_line.h | 290 + include/agg_ellipse.h | 123 + include/agg_ellipse_bresenham.h | 113 + include/agg_embedded_raster_fonts.h | 59 + include/agg_font_cache_manager.h | 409 + include/agg_font_cache_manager2.h | 311 + include/agg_gamma_functions.h | 131 + include/agg_gamma_lut.h | 307 + include/agg_glyph_raster_bin.h | 155 + include/agg_gradient_lut.h | 244 + include/agg_gsv_text.h | 153 + include/agg_image_accessors.h | 481 + include/agg_image_filters.h | 449 + include/agg_line_aa_basics.h | 189 + include/agg_math.h | 437 + include/agg_math_stroke.h | 524 + include/agg_path_length.h | 65 + include/agg_path_storage.h | 1581 +++ include/agg_path_storage_integer.h | 295 + include/agg_pattern_filters_rgba.h | 123 + include/agg_pixfmt_amask_adaptor.h | 240 + include/agg_pixfmt_base.h | 97 + include/agg_pixfmt_gray.h | 738 ++ include/agg_pixfmt_rgb.h | 995 ++ include/agg_pixfmt_rgb_packed.h | 1312 ++ include/agg_pixfmt_rgba.h | 2803 ++++ include/agg_pixfmt_transposer.h | 157 + include/agg_rasterizer_cells_aa.h | 742 ++ include/agg_rasterizer_compound_aa.h | 665 + include/agg_rasterizer_outline.h | 147 + include/agg_rasterizer_outline_aa.h | 600 + include/agg_rasterizer_scanline_aa.h | 481 + include/agg_rasterizer_scanline_aa_nogamma.h | 483 + include/agg_rasterizer_sl_clip.h | 351 + include/agg_renderer_base.h | 731 ++ include/agg_renderer_markers.h | 711 + include/agg_renderer_mclip.h | 349 + include/agg_renderer_outline_aa.h | 1838 +++ include/agg_renderer_outline_image.h | 1037 ++ include/agg_renderer_primitives.h | 224 + include/agg_renderer_raster_text.h | 264 + include/agg_renderer_scanline.h | 855 ++ include/agg_rendering_buffer.h | 301 + include/agg_rendering_buffer_dynarow.h | 138 + include/agg_rounded_rect.h | 72 + include/agg_scanline_bin.h | 264 + include/agg_scanline_boolean_algebra.h | 1566 +++ include/agg_scanline_p.h | 330 + include/agg_scanline_storage_aa.h | 815 ++ include/agg_scanline_storage_bin.h | 585 + include/agg_scanline_u.h | 500 + include/agg_shorten_path.h | 66 + include/agg_simul_eq.h | 147 + include/agg_span_allocator.h | 54 + include/agg_span_converter.h | 56 + include/agg_span_gouraud.h | 172 + include/agg_span_gouraud_gray.h | 243 + include/agg_span_gouraud_rgba.h | 278 + include/agg_span_gradient.h | 376 + include/agg_span_gradient_alpha.h | 126 + include/agg_span_gradient_contour.h | 364 + include/agg_span_gradient_image.h | 189 + include/agg_span_image_filter.h | 247 + include/agg_span_image_filter_gray.h | 723 ++ include/agg_span_image_filter_rgb.h | 861 ++ include/agg_span_image_filter_rgba.h | 890 ++ include/agg_span_interpolator_adaptor.h | 77 + include/agg_span_interpolator_linear.h | 232 + include/agg_span_interpolator_persp.h | 463 + include/agg_span_interpolator_trans.h | 92 + include/agg_span_pattern_gray.h | 93 + include/agg_span_pattern_rgb.h | 96 + include/agg_span_pattern_rgba.h | 94 + include/agg_span_solid.h | 53 + include/agg_span_subdiv_adaptor.h | 141 + include/agg_trans_affine.h | 518 + include/agg_trans_bilinear.h | 166 + include/agg_trans_double_path.h | 131 + include/agg_trans_perspective.h | 732 ++ include/agg_trans_single_path.h | 97 + include/agg_trans_viewport.h | 304 + include/agg_trans_warp_magnifier.h | 56 + include/agg_vcgen_bspline.h | 74 + include/agg_vcgen_contour.h | 94 + include/agg_vcgen_dash.h | 93 + include/agg_vcgen_markers_term.h | 66 + include/agg_vcgen_smooth_poly1.h | 87 + include/agg_vcgen_stroke.h | 102 + include/agg_vcgen_vertex_sequence.h | 135 + include/agg_vertex_sequence.h | 172 + include/agg_vpgen_clip_polygon.h | 83 + include/agg_vpgen_clip_polyline.h | 78 + include/agg_vpgen_segmentator.h | 60 + include/ctrl/Makefile.am | 4 + include/ctrl/agg_bezier_ctrl.h | 196 + include/ctrl/agg_cbox_ctrl.h | 112 + include/ctrl/agg_ctrl.h | 118 + include/ctrl/agg_gamma_ctrl.h | 170 + include/ctrl/agg_gamma_spline.h | 95 + include/ctrl/agg_polygon_ctrl.h | 166 + include/ctrl/agg_rbox_ctrl.h | 141 + include/ctrl/agg_scale_ctrl.h | 146 + include/ctrl/agg_slider_ctrl.h | 150 + include/ctrl/agg_spline_ctrl.h | 159 + include/platform/Makefile.am | 4 + include/platform/agg_platform_support.h | 686 + include/platform/mac/agg_mac_pmap.h | 86 + include/platform/win32/agg_win32_bmp.h | 116 + include/util/Makefile.am | 2 + include/util/agg_color_conv.h | 128 + include/util/agg_color_conv_rgb16.h | 285 + include/util/agg_color_conv_rgb8.h | 476 + install | 38 + libagg.m4 | 34 + libagg.pc.in | 10 + myapp/CMakeLists.txt | 85 + myapp/CMakeLists.txt.in | 85 + myapp/agg2d_demo.cpp | 403 + myapp/my_demo.cpp | 305 + myapp/myproject.cmake | 28 + src/CMakeLists.txt | 279 + src/Makefile | 60 + src/Makefile.am | 48 + src/agg_arc.cpp | 106 + src/agg_arrowhead.cpp | 110 + src/agg_bezier_arc.cpp | 258 + src/agg_bspline.cpp | 284 + src/agg_color_rgba.cpp | 17 + src/agg_curves.cpp | 613 + src/agg_embedded_raster_fonts.cpp | 10426 +++++++++++++++ src/agg_gsv_text.cpp | 677 + src/agg_image_filters.cpp | 103 + src/agg_line_aa_basics.cpp | 82 + src/agg_line_profile_aa.cpp | 116 + src/agg_rounded_rect.cpp | 164 + src/agg_sqrt_tables.cpp | 115 + src/agg_trans_affine.cpp | 194 + src/agg_trans_double_path.cpp | 273 + src/agg_trans_single_path.cpp | 202 + src/agg_trans_warp_magnifier.cpp | 70 + src/agg_vcgen_bspline.cpp | 194 + src/agg_vcgen_contour.cpp | 164 + src/agg_vcgen_dash.cpp | 235 + src/agg_vcgen_markers_term.cpp | 103 + src/agg_vcgen_smooth_poly1.cpp | 225 + src/agg_vcgen_stroke.cpp | 212 + src/agg_vpgen_clip_polygon.cpp | 133 + src/agg_vpgen_clip_polyline.cpp | 77 + src/agg_vpgen_segmentator.cpp | 67 + src/ctrl/Makefile.am | 11 + src/ctrl/agg_bezier_ctrl.cpp | 370 + src/ctrl/agg_cbox_ctrl.cpp | 214 + src/ctrl/agg_gamma_ctrl.cpp | 433 + src/ctrl/agg_gamma_spline.cpp | 130 + src/ctrl/agg_polygon_ctrl.cpp | 332 + src/ctrl/agg_rbox_ctrl.cpp | 325 + src/ctrl/agg_scale_ctrl.cpp | 454 + src/ctrl/agg_slider_ctrl.cpp | 349 + src/ctrl/agg_spline_ctrl.cpp | 407 + src/platform/AmigaOS/Makefile.am | 1 + src/platform/AmigaOS/agg_platform_support.cpp | 977 ++ src/platform/BeOS/Makefile.am | 1 + src/platform/BeOS/agg_platform_support.cpp | 990 ++ src/platform/Makefile.am | 1 + src/platform/X11/Makefile.am | 8 + src/platform/X11/agg_platform_support.cpp | 1605 +++ src/platform/mac/Makefile.am | 11 + src/platform/mac/agg_mac_pmap.cpp | 298 + src/platform/mac/agg_platform_support.cpp | 1053 ++ src/platform/sdl/Makefile.am | 10 + src/platform/sdl/agg_platform_support.cpp | 709 + src/platform/win32/Makefile.am | 13 + src/platform/win32/agg_platform_support.cpp | 1655 +++ src/platform/win32/agg_win32_bmp.cpp | 633 + 645 files changed, 163875 insertions(+) create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 ChangeLog create mode 100644 Makefile create mode 100644 Makefile.AmigaOS create mode 100644 Makefile.am create mode 100644 Makefile.in.BeOS create mode 100644 Makefile.in.CYGWIN_NT-5.0 create mode 100644 Makefile.in.CYGWIN_NT-5.1 create mode 100644 Makefile.in.Darwin create mode 100644 Makefile.in.Darwin.SDL create mode 100644 Makefile.in.IRIX64 create mode 100644 Makefile.in.Linux create mode 100644 Makefile.in.Linux.SDL create mode 100644 Makefile.in.MINGW32_NT-5.0 create mode 100644 Makefile.in.MINGW32_NT-5.1 create mode 100644 Makefile.in.SunOS create mode 100644 NEWS create mode 100644 README create mode 100644 agg2d/agg2d.cpp create mode 100644 agg2d/agg2d.h create mode 100644 autogen.sh create mode 100644 bin/AggConfig.cmake.in create mode 100644 bin/AggConfigOutBuild.cmake.in create mode 100644 bin/FindAgg.cmake create mode 100644 bin/FindEXPAT.cmake create mode 100644 bin/FindFreetype.cmake create mode 100644 bin/UseAgg.cmake.in create mode 100644 cmake_install.html create mode 100644 configure.ac create mode 100644 copying create mode 100644 distclean create mode 100644 doc/AggCP-Gradients1_readme.txt create mode 100644 examples/BeOS/Makefile create mode 100644 examples/BeOS/readme.txt create mode 100644 examples/CMakeLists.txt create mode 100644 examples/Makefile.am create mode 100644 examples/X11/Makefile create mode 100644 examples/X11/readme.txt create mode 100644 examples/aa_demo.cpp create mode 100644 examples/aa_test.cpp create mode 100644 examples/agg2d_demo.cpp create mode 100644 examples/alpha_gradient.cpp create mode 100644 examples/alpha_mask.cpp create mode 100644 examples/alpha_mask2.cpp create mode 100644 examples/alpha_mask3.cpp create mode 100644 examples/art/1.sdf create mode 100644 examples/art/agg.bmp create mode 100644 examples/art/agg.ppm create mode 100644 examples/art/compositing.bmp create mode 100644 examples/art/compositing.ppm create mode 100644 examples/art/line_patterns.bmp.zip create mode 100644 examples/art/line_patterns.tar.gz create mode 100644 examples/art/shapes.txt create mode 100644 examples/art/spheres.bmp create mode 100644 examples/art/spheres.ppm create mode 100644 examples/art/tiger.svg create mode 100644 examples/art/timesi.zip create mode 100644 examples/bezier_div.cpp create mode 100644 examples/blend_color.cpp create mode 100644 examples/blur.cpp create mode 100644 examples/bspline.cpp create mode 100644 examples/circles.cpp create mode 100644 examples/component_rendering.cpp create mode 100644 examples/compositing.cpp create mode 100644 examples/compositing2.cpp create mode 100644 examples/conv_contour.cpp create mode 100644 examples/conv_dash_marker.cpp create mode 100644 examples/conv_stroke.cpp create mode 100644 examples/distortions.cpp create mode 100644 examples/flash_rasterizer.cpp create mode 100644 examples/flash_rasterizer2.cpp create mode 100644 examples/freetype_test.cpp create mode 100644 examples/gamma_correction.cpp create mode 100644 examples/gamma_ctrl.cpp create mode 100644 examples/gamma_tuner.cpp create mode 100644 examples/gouraud.cpp create mode 100644 examples/gouraud_mesh.cpp create mode 100644 examples/gpc_test.cpp create mode 100644 examples/gradient_focal.cpp create mode 100644 examples/gradients.cpp create mode 100644 examples/gradients_contour.cpp create mode 100644 examples/graph_test.cpp create mode 100644 examples/idea.cpp create mode 100644 examples/image1.cpp create mode 100644 examples/image_alpha.cpp create mode 100644 examples/image_filters.cpp create mode 100644 examples/image_filters2.cpp create mode 100644 examples/image_fltr_graph.cpp create mode 100644 examples/image_perspective.cpp create mode 100644 examples/image_resample.cpp create mode 100644 examples/image_transforms.cpp create mode 100644 examples/interactive_polygon.cpp create mode 100644 examples/interactive_polygon.h create mode 100644 examples/line_patterns.cpp create mode 100644 examples/line_patterns_clip.cpp create mode 100644 examples/line_thickness.cpp create mode 100644 examples/lion.cpp create mode 100644 examples/lion_lens.cpp create mode 100644 examples/lion_outline.cpp create mode 100644 examples/macosx_carbon/Makefile create mode 100644 examples/macosx_carbon/readme.txt create mode 100644 examples/macosx_sdl/Makefile create mode 100644 examples/macosx_sdl/readme.txt create mode 100644 examples/make_arrows.cpp create mode 100644 examples/make_gb_poly.cpp create mode 100644 examples/mol_view.cpp create mode 100644 examples/multi_clip.cpp create mode 100644 examples/parse_lion.cpp create mode 100644 examples/pattern_fill.cpp create mode 100644 examples/pattern_perspective.cpp create mode 100644 examples/pattern_resample.cpp create mode 100644 examples/perspective.cpp create mode 100644 examples/pixel_formats.h create mode 100644 examples/polymorphic_renderer.cpp create mode 100644 examples/raster_text.cpp create mode 100644 examples/rasterizer_compound.cpp create mode 100644 examples/rasterizers.cpp create mode 100644 examples/rasterizers2.cpp create mode 100644 examples/rounded_rect.cpp create mode 100644 examples/scanline_boolean.cpp create mode 100644 examples/scanline_boolean2.cpp create mode 100644 examples/simple_blur.cpp create mode 100644 examples/svg_viewer/agg_svg_exception.h create mode 100644 examples/svg_viewer/agg_svg_parser.cpp create mode 100644 examples/svg_viewer/agg_svg_parser.h create mode 100644 examples/svg_viewer/agg_svg_path_renderer.cpp create mode 100644 examples/svg_viewer/agg_svg_path_renderer.h create mode 100644 examples/svg_viewer/agg_svg_path_tokenizer.cpp create mode 100644 examples/svg_viewer/agg_svg_path_tokenizer.h create mode 100644 examples/svg_viewer/svg_test.cpp create mode 100644 examples/trans_curve1.cpp create mode 100644 examples/trans_curve1_ft.cpp create mode 100644 examples/trans_curve2.cpp create mode 100644 examples/trans_curve2_ft.cpp create mode 100644 examples/trans_polar.cpp create mode 100644 examples/truetype_test.cpp create mode 100644 examples/win32_api/Makefile create mode 100644 examples/win32_api/aa_demo/Makefile create mode 100644 examples/win32_api/aa_demo/aa_demo.dsp create mode 100644 examples/win32_api/aa_demo/aa_demo.dsw create mode 100644 examples/win32_api/aa_demo/aa_demo.vcxproj create mode 100644 examples/win32_api/aa_test/Makefile create mode 100644 examples/win32_api/aa_test/aa_test.dsp create mode 100644 examples/win32_api/aa_test/aa_test.dsw create mode 100644 examples/win32_api/aa_test/aa_test.vcxproj create mode 100644 examples/win32_api/agg.props create mode 100644 examples/win32_api/agg2d_demo/Makefile create mode 100644 examples/win32_api/agg2d_demo/agg2d_demo.vcxproj create mode 100644 examples/win32_api/alpha_gradient/Makefile create mode 100644 examples/win32_api/alpha_gradient/alpha_gradient.dsp create mode 100644 examples/win32_api/alpha_gradient/alpha_gradient.dsw create mode 100644 examples/win32_api/alpha_gradient/alpha_gradient.vcxproj create mode 100644 examples/win32_api/alpha_mask/Makefile create mode 100644 examples/win32_api/alpha_mask/alpha_mask.dsp create mode 100644 examples/win32_api/alpha_mask/alpha_mask.dsw create mode 100644 examples/win32_api/alpha_mask/alpha_mask.vcxproj create mode 100644 examples/win32_api/alpha_mask2/Makefile create mode 100644 examples/win32_api/alpha_mask2/alpha_mask2.dsp create mode 100644 examples/win32_api/alpha_mask2/alpha_mask2.dsw create mode 100644 examples/win32_api/alpha_mask2/alpha_mask2.vcxproj create mode 100644 examples/win32_api/alpha_mask3/Makefile create mode 100644 examples/win32_api/alpha_mask3/alpha_mask3.dsp create mode 100644 examples/win32_api/alpha_mask3/alpha_mask3.dsw create mode 100644 examples/win32_api/alpha_mask3/alpha_mask3.vcxproj create mode 100644 examples/win32_api/bezier_div/Makefile create mode 100644 examples/win32_api/bezier_div/bezier_div.dsp create mode 100644 examples/win32_api/bezier_div/bezier_div.dsw create mode 100644 examples/win32_api/bezier_div/bezier_div.vcxproj create mode 100644 examples/win32_api/blend_color/Makefile create mode 100644 examples/win32_api/blend_color/blend_color.dsp create mode 100644 examples/win32_api/blend_color/blend_color.dsw create mode 100644 examples/win32_api/blend_color/blend_color.vcxproj create mode 100644 examples/win32_api/blur/Makefile create mode 100644 examples/win32_api/blur/blur.dsp create mode 100644 examples/win32_api/blur/blur.dsw create mode 100644 examples/win32_api/blur/blur.vcxproj create mode 100644 examples/win32_api/bspline/Makefile create mode 100644 examples/win32_api/bspline/bspline.dsp create mode 100644 examples/win32_api/bspline/bspline.dsw create mode 100644 examples/win32_api/bspline/bspline.vcxproj create mode 100644 examples/win32_api/circles/Makefile create mode 100644 examples/win32_api/circles/circles.dsp create mode 100644 examples/win32_api/circles/circles.dsw create mode 100644 examples/win32_api/circles/circles.vcxproj create mode 100644 examples/win32_api/component_rendering/Makefile create mode 100644 examples/win32_api/component_rendering/component_rendering.dsp create mode 100644 examples/win32_api/component_rendering/component_rendering.dsw create mode 100644 examples/win32_api/component_rendering/component_rendering.vcxproj create mode 100644 examples/win32_api/compositing/Makefile create mode 100644 examples/win32_api/compositing/compositing.dsp create mode 100644 examples/win32_api/compositing/compositing.dsw create mode 100644 examples/win32_api/compositing/compositing.vcxproj create mode 100644 examples/win32_api/compositing/readme create mode 100644 examples/win32_api/compositing2/Makefile create mode 100644 examples/win32_api/compositing2/compositing2.dsp create mode 100644 examples/win32_api/compositing2/compositing2.dsw create mode 100644 examples/win32_api/compositing2/compositing2.vcxproj create mode 100644 examples/win32_api/conv_contour/Makefile create mode 100644 examples/win32_api/conv_contour/conv_contour.dsp create mode 100644 examples/win32_api/conv_contour/conv_contour.dsw create mode 100644 examples/win32_api/conv_contour/conv_contour.vcxproj create mode 100644 examples/win32_api/conv_dash_marker/Makefile create mode 100644 examples/win32_api/conv_dash_marker/conv_dash_marker.dsp create mode 100644 examples/win32_api/conv_dash_marker/conv_dash_marker.dsw create mode 100644 examples/win32_api/conv_dash_marker/conv_dash_marker.vcxproj create mode 100644 examples/win32_api/conv_stroke/Makefile create mode 100644 examples/win32_api/conv_stroke/conv_stroke.dsp create mode 100644 examples/win32_api/conv_stroke/conv_stroke.dsw create mode 100644 examples/win32_api/conv_stroke/conv_stroke.vcxproj create mode 100644 examples/win32_api/distortions/Makefile create mode 100644 examples/win32_api/distortions/distortions.dsp create mode 100644 examples/win32_api/distortions/distortions.dsw create mode 100644 examples/win32_api/distortions/distortions.vcxproj create mode 100644 examples/win32_api/distortions/readme create mode 100644 examples/win32_api/examples.dsw create mode 100644 examples/win32_api/examples.sln create mode 100644 examples/win32_api/flash_rasterizer/Makefile create mode 100644 examples/win32_api/flash_rasterizer/flash_rasterizer.dsp create mode 100644 examples/win32_api/flash_rasterizer/flash_rasterizer.dsw create mode 100644 examples/win32_api/flash_rasterizer/flash_rasterizer.vcxproj create mode 100644 examples/win32_api/flash_rasterizer2/Makefile create mode 100644 examples/win32_api/flash_rasterizer2/flash_rasterizer2.dsp create mode 100644 examples/win32_api/flash_rasterizer2/flash_rasterizer2.dsw create mode 100644 examples/win32_api/flash_rasterizer2/flash_rasterizer2.vcxproj create mode 100644 examples/win32_api/freetype_test/Makefile create mode 100644 examples/win32_api/freetype_test/freetype_test.dsp create mode 100644 examples/win32_api/freetype_test/freetype_test.dsw create mode 100644 examples/win32_api/freetype_test/freetype_test.vcxproj create mode 100644 examples/win32_api/freetype_test/readme create mode 100644 examples/win32_api/gamma_correction/Makefile create mode 100644 examples/win32_api/gamma_correction/gamma_correction.dsp create mode 100644 examples/win32_api/gamma_correction/gamma_correction.dsw create mode 100644 examples/win32_api/gamma_correction/gamma_correction.vcxproj create mode 100644 examples/win32_api/gamma_ctrl/Makefile create mode 100644 examples/win32_api/gamma_ctrl/gamma_ctrl.dsp create mode 100644 examples/win32_api/gamma_ctrl/gamma_ctrl.dsw create mode 100644 examples/win32_api/gamma_ctrl/gamma_ctrl.vcxproj create mode 100644 examples/win32_api/gamma_tuner/Makefile create mode 100644 examples/win32_api/gamma_tuner/gamma_tuner.dsp create mode 100644 examples/win32_api/gamma_tuner/gamma_tuner.dsw create mode 100644 examples/win32_api/gamma_tuner/gamma_tuner.vcxproj create mode 100644 examples/win32_api/gouraud/Makefile create mode 100644 examples/win32_api/gouraud/gouraud.dsp create mode 100644 examples/win32_api/gouraud/gouraud.dsw create mode 100644 examples/win32_api/gouraud/gouraud.vcxproj create mode 100644 examples/win32_api/gouraud_mesh/Makefile create mode 100644 examples/win32_api/gouraud_mesh/gouraud_mesh.dsp create mode 100644 examples/win32_api/gouraud_mesh/gouraud_mesh.dsw create mode 100644 examples/win32_api/gouraud_mesh/gouraud_mesh.vcxproj create mode 100644 examples/win32_api/gpc_test/Makefile create mode 100644 examples/win32_api/gpc_test/gpc_test.dsp create mode 100644 examples/win32_api/gpc_test/gpc_test.dsw create mode 100644 examples/win32_api/gpc_test/gpc_test.vcxproj create mode 100644 examples/win32_api/gradient_focal/Makefile create mode 100644 examples/win32_api/gradient_focal/gradient_focal.dsp create mode 100644 examples/win32_api/gradient_focal/gradient_focal.dsw create mode 100644 examples/win32_api/gradient_focal/gradient_focal.vcxproj create mode 100644 examples/win32_api/gradients/Makefile create mode 100644 examples/win32_api/gradients/gradients.dsp create mode 100644 examples/win32_api/gradients/gradients.dsw create mode 100644 examples/win32_api/gradients/gradients.vcxproj create mode 100644 examples/win32_api/gradients/settings.dat create mode 100644 examples/win32_api/graph_test/Makefile create mode 100644 examples/win32_api/graph_test/graph_test.dsp create mode 100644 examples/win32_api/graph_test/graph_test.dsw create mode 100644 examples/win32_api/graph_test/graph_test.vcxproj create mode 100644 examples/win32_api/idea/Makefile create mode 100644 examples/win32_api/idea/idea.dsp create mode 100644 examples/win32_api/idea/idea.dsw create mode 100644 examples/win32_api/idea/idea.vcxproj create mode 100644 examples/win32_api/image1/Makefile create mode 100644 examples/win32_api/image1/image1.dsp create mode 100644 examples/win32_api/image1/image1.dsw create mode 100644 examples/win32_api/image1/image1.vcxproj create mode 100644 examples/win32_api/image1/readme create mode 100644 examples/win32_api/image_alpha/Makefile create mode 100644 examples/win32_api/image_alpha/image_alpha.dsp create mode 100644 examples/win32_api/image_alpha/image_alpha.dsw create mode 100644 examples/win32_api/image_alpha/image_alpha.vcxproj create mode 100644 examples/win32_api/image_alpha/readme create mode 100644 examples/win32_api/image_filters/Makefile create mode 100644 examples/win32_api/image_filters/image_filters.dsp create mode 100644 examples/win32_api/image_filters/image_filters.dsw create mode 100644 examples/win32_api/image_filters/image_filters.vcxproj create mode 100644 examples/win32_api/image_filters/readme create mode 100644 examples/win32_api/image_filters2/Makefile create mode 100644 examples/win32_api/image_filters2/image_filters2.dsp create mode 100644 examples/win32_api/image_filters2/image_filters2.dsw create mode 100644 examples/win32_api/image_filters2/image_filters2.vcxproj create mode 100644 examples/win32_api/image_filters2/readme create mode 100644 examples/win32_api/image_fltr_graph/Makefile create mode 100644 examples/win32_api/image_fltr_graph/image_fltr_graph.dsp create mode 100644 examples/win32_api/image_fltr_graph/image_fltr_graph.dsw create mode 100644 examples/win32_api/image_fltr_graph/image_fltr_graph.vcxproj create mode 100644 examples/win32_api/image_perspective/Makefile create mode 100644 examples/win32_api/image_perspective/image_perspective.dsp create mode 100644 examples/win32_api/image_perspective/image_perspective.dsw create mode 100644 examples/win32_api/image_perspective/image_perspective.vcxproj create mode 100644 examples/win32_api/image_perspective/readme create mode 100644 examples/win32_api/image_resample/Makefile create mode 100644 examples/win32_api/image_resample/image_resample.dsp create mode 100644 examples/win32_api/image_resample/image_resample.dsw create mode 100644 examples/win32_api/image_resample/image_resample.vcxproj create mode 100644 examples/win32_api/image_resample/readme create mode 100644 examples/win32_api/image_transforms/Makefile create mode 100644 examples/win32_api/image_transforms/image_transforms.dsp create mode 100644 examples/win32_api/image_transforms/image_transforms.dsw create mode 100644 examples/win32_api/image_transforms/image_transforms.vcxproj create mode 100644 examples/win32_api/image_transforms/readme! create mode 100644 examples/win32_api/line_patterns/Makefile create mode 100644 examples/win32_api/line_patterns/line_patterns.dsp create mode 100644 examples/win32_api/line_patterns/line_patterns.dsw create mode 100644 examples/win32_api/line_patterns/line_patterns.vcxproj create mode 100644 examples/win32_api/line_patterns_clip/Makefile create mode 100644 examples/win32_api/line_patterns_clip/line_patterns_clip.dsp create mode 100644 examples/win32_api/line_patterns_clip/line_patterns_clip.dsw create mode 100644 examples/win32_api/line_patterns_clip/line_patterns_clip.vcxproj create mode 100644 examples/win32_api/line_thickness/line_thickness.vcxproj create mode 100644 examples/win32_api/lion/Makefile create mode 100644 examples/win32_api/lion/lion.dsp create mode 100644 examples/win32_api/lion/lion.dsw create mode 100644 examples/win32_api/lion/lion.vcxproj create mode 100644 examples/win32_api/lion_lens/Makefile create mode 100644 examples/win32_api/lion_lens/lion_lens.dsp create mode 100644 examples/win32_api/lion_lens/lion_lens.dsw create mode 100644 examples/win32_api/lion_lens/lion_lens.vcxproj create mode 100644 examples/win32_api/lion_outline/Makefile create mode 100644 examples/win32_api/lion_outline/lion_outline.dsp create mode 100644 examples/win32_api/lion_outline/lion_outline.dsw create mode 100644 examples/win32_api/lion_outline/lion_outline.vcxproj create mode 100644 examples/win32_api/mol_view/Makefile create mode 100644 examples/win32_api/mol_view/mol_view.dsp create mode 100644 examples/win32_api/mol_view/mol_view.dsw create mode 100644 examples/win32_api/mol_view/mol_view.vcxproj create mode 100644 examples/win32_api/mol_view/readme create mode 100644 examples/win32_api/multi_clip/Makefile create mode 100644 examples/win32_api/multi_clip/multi_clip.dsp create mode 100644 examples/win32_api/multi_clip/multi_clip.dsw create mode 100644 examples/win32_api/multi_clip/multi_clip.vcxproj create mode 100644 examples/win32_api/pattern_fill/Makefile create mode 100644 examples/win32_api/pattern_fill/pattern_fill.dsp create mode 100644 examples/win32_api/pattern_fill/pattern_fill.dsw create mode 100644 examples/win32_api/pattern_fill/pattern_fill.vcxproj create mode 100644 examples/win32_api/pattern_perspective/pattern_perspective.dsp create mode 100644 examples/win32_api/pattern_perspective/pattern_perspective.dsw create mode 100644 examples/win32_api/pattern_perspective/pattern_perspective.vcxproj create mode 100644 examples/win32_api/pattern_resample/Makefile create mode 100644 examples/win32_api/pattern_resample/pattern_resample.dsp create mode 100644 examples/win32_api/pattern_resample/pattern_resample.dsw create mode 100644 examples/win32_api/pattern_resample/pattern_resample.vcxproj create mode 100644 examples/win32_api/perspective/Makefile create mode 100644 examples/win32_api/perspective/perspective.dsp create mode 100644 examples/win32_api/perspective/perspective.dsw create mode 100644 examples/win32_api/perspective/perspective.vcxproj create mode 100644 examples/win32_api/polymorphic_renderer/Makefile create mode 100644 examples/win32_api/polymorphic_renderer/polymorphic_renderer.dsp create mode 100644 examples/win32_api/polymorphic_renderer/polymorphic_renderer.dsw create mode 100644 examples/win32_api/polymorphic_renderer/polymorphic_renderer.vcxproj create mode 100644 examples/win32_api/pure_api/StdAfx.cpp create mode 100644 examples/win32_api/pure_api/StdAfx.h create mode 100644 examples/win32_api/pure_api/pure_api.cpp create mode 100644 examples/win32_api/pure_api/pure_api.dsp create mode 100644 examples/win32_api/pure_api/pure_api.dsw create mode 100644 examples/win32_api/pure_api/pure_api.h create mode 100644 examples/win32_api/pure_api/pure_api.ico create mode 100644 examples/win32_api/pure_api/pure_api.rc create mode 100644 examples/win32_api/pure_api/pure_api.vcxproj create mode 100644 examples/win32_api/pure_api/resource.h create mode 100644 examples/win32_api/pure_api/small.ico create mode 100644 examples/win32_api/raster_text/Makefile create mode 100644 examples/win32_api/raster_text/raster_text.dsp create mode 100644 examples/win32_api/raster_text/raster_text.dsw create mode 100644 examples/win32_api/raster_text/raster_text.vcxproj create mode 100644 examples/win32_api/rasterizer_compound/Makefile create mode 100644 examples/win32_api/rasterizer_compound/rasterizer_compound.dsp create mode 100644 examples/win32_api/rasterizer_compound/rasterizer_compound.dsw create mode 100644 examples/win32_api/rasterizer_compound/rasterizer_compound.vcxproj create mode 100644 examples/win32_api/rasterizers/Makefile create mode 100644 examples/win32_api/rasterizers/rasterizers.dsp create mode 100644 examples/win32_api/rasterizers/rasterizers.dsw create mode 100644 examples/win32_api/rasterizers/rasterizers.vcxproj create mode 100644 examples/win32_api/rasterizers2/Makefile create mode 100644 examples/win32_api/rasterizers2/rasterizers2.dsp create mode 100644 examples/win32_api/rasterizers2/rasterizers2.dsw create mode 100644 examples/win32_api/rasterizers2/rasterizers2.vcxproj create mode 100644 examples/win32_api/rounded_rect/Makefile create mode 100644 examples/win32_api/rounded_rect/rounded_rect.dsp create mode 100644 examples/win32_api/rounded_rect/rounded_rect.dsw create mode 100644 examples/win32_api/rounded_rect/rounded_rect.vcxproj create mode 100644 examples/win32_api/scanline_boolean/Makefile create mode 100644 examples/win32_api/scanline_boolean/scanline_boolean.dsp create mode 100644 examples/win32_api/scanline_boolean/scanline_boolean.dsw create mode 100644 examples/win32_api/scanline_boolean/scanline_boolean.vcxproj create mode 100644 examples/win32_api/scanline_boolean2/Makefile create mode 100644 examples/win32_api/scanline_boolean2/scanline_boolean2.dsp create mode 100644 examples/win32_api/scanline_boolean2/scanline_boolean2.dsw create mode 100644 examples/win32_api/scanline_boolean2/scanline_boolean2.vcxproj create mode 100644 examples/win32_api/simple_blur/Makefile create mode 100644 examples/win32_api/simple_blur/simple_blur.dsp create mode 100644 examples/win32_api/simple_blur/simple_blur.dsw create mode 100644 examples/win32_api/simple_blur/simple_blur.vcxproj create mode 100644 examples/win32_api/svg_test/svg_test.dsp create mode 100644 examples/win32_api/svg_test/svg_test.dsw create mode 100644 examples/win32_api/svg_test/svg_test.vcxproj create mode 100644 examples/win32_api/trans_curve1/Makefile create mode 100644 examples/win32_api/trans_curve1/trans_curve1.dsp create mode 100644 examples/win32_api/trans_curve1/trans_curve1.dsw create mode 100644 examples/win32_api/trans_curve1/trans_curve1.vcxproj create mode 100644 examples/win32_api/trans_curve2/Makefile create mode 100644 examples/win32_api/trans_curve2/trans_curve2.dsp create mode 100644 examples/win32_api/trans_curve2/trans_curve2.dsw create mode 100644 examples/win32_api/trans_curve2/trans_curve2.vcxproj create mode 100644 examples/win32_api/trans_polar/Makefile create mode 100644 examples/win32_api/trans_polar/trans_polar.dsp create mode 100644 examples/win32_api/trans_polar/trans_polar.dsw create mode 100644 examples/win32_api/trans_polar/trans_polar.vcxproj create mode 100644 examples/win32_api/truetype_test/Makefile create mode 100644 examples/win32_api/truetype_test/truetype_test.dsp create mode 100644 examples/win32_api/truetype_test/truetype_test.dsw create mode 100644 examples/win32_api/truetype_test/truetype_test.vcxproj create mode 100644 examples/win32_api_dmc/Makefile create mode 100644 examples/win32_api_dmc/readme create mode 100644 font_freetype/Makefile.am create mode 100644 font_freetype/agg_font_freetype.cpp create mode 100644 font_freetype/agg_font_freetype.h create mode 100644 font_freetype/agg_font_freetype2.cpp create mode 100644 font_freetype/agg_font_freetype2.h create mode 100644 font_win32_tt/Makefile.am create mode 100644 font_win32_tt/agg_font_win32_tt.cpp create mode 100644 font_win32_tt/agg_font_win32_tt.h create mode 100644 gpc/Makefile.am create mode 100644 gpc/VERSIONS.TXT create mode 100644 gpc/copying.txt create mode 100644 gpc/gpc.c create mode 100644 gpc/gpc.h create mode 100644 include/Makefile.am create mode 100644 include/agg_alpha_mask_u8.h create mode 100644 include/agg_arc.h create mode 100644 include/agg_array.h create mode 100644 include/agg_arrowhead.h create mode 100644 include/agg_basics.h create mode 100644 include/agg_bezier_arc.h create mode 100644 include/agg_bitset_iterator.h create mode 100644 include/agg_blur.h create mode 100644 include/agg_bounding_rect.h create mode 100644 include/agg_bspline.h create mode 100644 include/agg_clip_liang_barsky.h create mode 100644 include/agg_color_gray.h create mode 100644 include/agg_color_rgba.h create mode 100644 include/agg_config.h create mode 100644 include/agg_conv_adaptor_vcgen.h create mode 100644 include/agg_conv_adaptor_vpgen.h create mode 100644 include/agg_conv_bspline.h create mode 100644 include/agg_conv_clip_polygon.h create mode 100644 include/agg_conv_clip_polyline.h create mode 100644 include/agg_conv_close_polygon.h create mode 100644 include/agg_conv_concat.h create mode 100644 include/agg_conv_contour.h create mode 100644 include/agg_conv_curve.h create mode 100644 include/agg_conv_dash.h create mode 100644 include/agg_conv_gpc.h create mode 100644 include/agg_conv_marker.h create mode 100644 include/agg_conv_marker_adaptor.h create mode 100644 include/agg_conv_segmentator.h create mode 100644 include/agg_conv_shorten_path.h create mode 100644 include/agg_conv_smooth_poly1.h create mode 100644 include/agg_conv_stroke.h create mode 100644 include/agg_conv_transform.h create mode 100644 include/agg_conv_unclose_polygon.h create mode 100644 include/agg_curves.h create mode 100644 include/agg_dda_line.h create mode 100644 include/agg_ellipse.h create mode 100644 include/agg_ellipse_bresenham.h create mode 100644 include/agg_embedded_raster_fonts.h create mode 100644 include/agg_font_cache_manager.h create mode 100644 include/agg_font_cache_manager2.h create mode 100644 include/agg_gamma_functions.h create mode 100644 include/agg_gamma_lut.h create mode 100644 include/agg_glyph_raster_bin.h create mode 100644 include/agg_gradient_lut.h create mode 100644 include/agg_gsv_text.h create mode 100644 include/agg_image_accessors.h create mode 100644 include/agg_image_filters.h create mode 100644 include/agg_line_aa_basics.h create mode 100644 include/agg_math.h create mode 100644 include/agg_math_stroke.h create mode 100644 include/agg_path_length.h create mode 100644 include/agg_path_storage.h create mode 100644 include/agg_path_storage_integer.h create mode 100644 include/agg_pattern_filters_rgba.h create mode 100644 include/agg_pixfmt_amask_adaptor.h create mode 100644 include/agg_pixfmt_base.h create mode 100644 include/agg_pixfmt_gray.h create mode 100644 include/agg_pixfmt_rgb.h create mode 100644 include/agg_pixfmt_rgb_packed.h create mode 100644 include/agg_pixfmt_rgba.h create mode 100644 include/agg_pixfmt_transposer.h create mode 100644 include/agg_rasterizer_cells_aa.h create mode 100644 include/agg_rasterizer_compound_aa.h create mode 100644 include/agg_rasterizer_outline.h create mode 100644 include/agg_rasterizer_outline_aa.h create mode 100644 include/agg_rasterizer_scanline_aa.h create mode 100644 include/agg_rasterizer_scanline_aa_nogamma.h create mode 100644 include/agg_rasterizer_sl_clip.h create mode 100644 include/agg_renderer_base.h create mode 100644 include/agg_renderer_markers.h create mode 100644 include/agg_renderer_mclip.h create mode 100644 include/agg_renderer_outline_aa.h create mode 100644 include/agg_renderer_outline_image.h create mode 100644 include/agg_renderer_primitives.h create mode 100644 include/agg_renderer_raster_text.h create mode 100644 include/agg_renderer_scanline.h create mode 100644 include/agg_rendering_buffer.h create mode 100644 include/agg_rendering_buffer_dynarow.h create mode 100644 include/agg_rounded_rect.h create mode 100644 include/agg_scanline_bin.h create mode 100644 include/agg_scanline_boolean_algebra.h create mode 100644 include/agg_scanline_p.h create mode 100644 include/agg_scanline_storage_aa.h create mode 100644 include/agg_scanline_storage_bin.h create mode 100644 include/agg_scanline_u.h create mode 100644 include/agg_shorten_path.h create mode 100644 include/agg_simul_eq.h create mode 100644 include/agg_span_allocator.h create mode 100644 include/agg_span_converter.h create mode 100644 include/agg_span_gouraud.h create mode 100644 include/agg_span_gouraud_gray.h create mode 100644 include/agg_span_gouraud_rgba.h create mode 100644 include/agg_span_gradient.h create mode 100644 include/agg_span_gradient_alpha.h create mode 100644 include/agg_span_gradient_contour.h create mode 100644 include/agg_span_gradient_image.h create mode 100644 include/agg_span_image_filter.h create mode 100644 include/agg_span_image_filter_gray.h create mode 100644 include/agg_span_image_filter_rgb.h create mode 100644 include/agg_span_image_filter_rgba.h create mode 100644 include/agg_span_interpolator_adaptor.h create mode 100644 include/agg_span_interpolator_linear.h create mode 100644 include/agg_span_interpolator_persp.h create mode 100644 include/agg_span_interpolator_trans.h create mode 100644 include/agg_span_pattern_gray.h create mode 100644 include/agg_span_pattern_rgb.h create mode 100644 include/agg_span_pattern_rgba.h create mode 100644 include/agg_span_solid.h create mode 100644 include/agg_span_subdiv_adaptor.h create mode 100644 include/agg_trans_affine.h create mode 100644 include/agg_trans_bilinear.h create mode 100644 include/agg_trans_double_path.h create mode 100644 include/agg_trans_perspective.h create mode 100644 include/agg_trans_single_path.h create mode 100644 include/agg_trans_viewport.h create mode 100644 include/agg_trans_warp_magnifier.h create mode 100644 include/agg_vcgen_bspline.h create mode 100644 include/agg_vcgen_contour.h create mode 100644 include/agg_vcgen_dash.h create mode 100644 include/agg_vcgen_markers_term.h create mode 100644 include/agg_vcgen_smooth_poly1.h create mode 100644 include/agg_vcgen_stroke.h create mode 100644 include/agg_vcgen_vertex_sequence.h create mode 100644 include/agg_vertex_sequence.h create mode 100644 include/agg_vpgen_clip_polygon.h create mode 100644 include/agg_vpgen_clip_polyline.h create mode 100644 include/agg_vpgen_segmentator.h create mode 100644 include/ctrl/Makefile.am create mode 100644 include/ctrl/agg_bezier_ctrl.h create mode 100644 include/ctrl/agg_cbox_ctrl.h create mode 100644 include/ctrl/agg_ctrl.h create mode 100644 include/ctrl/agg_gamma_ctrl.h create mode 100644 include/ctrl/agg_gamma_spline.h create mode 100644 include/ctrl/agg_polygon_ctrl.h create mode 100644 include/ctrl/agg_rbox_ctrl.h create mode 100644 include/ctrl/agg_scale_ctrl.h create mode 100644 include/ctrl/agg_slider_ctrl.h create mode 100644 include/ctrl/agg_spline_ctrl.h create mode 100644 include/platform/Makefile.am create mode 100644 include/platform/agg_platform_support.h create mode 100644 include/platform/mac/agg_mac_pmap.h create mode 100644 include/platform/win32/agg_win32_bmp.h create mode 100644 include/util/Makefile.am create mode 100644 include/util/agg_color_conv.h create mode 100644 include/util/agg_color_conv_rgb16.h create mode 100644 include/util/agg_color_conv_rgb8.h create mode 100644 install create mode 100644 libagg.m4 create mode 100644 libagg.pc.in create mode 100644 myapp/CMakeLists.txt create mode 100644 myapp/CMakeLists.txt.in create mode 100644 myapp/agg2d_demo.cpp create mode 100644 myapp/my_demo.cpp create mode 100644 myapp/myproject.cmake create mode 100644 src/CMakeLists.txt create mode 100644 src/Makefile create mode 100644 src/Makefile.am create mode 100644 src/agg_arc.cpp create mode 100644 src/agg_arrowhead.cpp create mode 100644 src/agg_bezier_arc.cpp create mode 100644 src/agg_bspline.cpp create mode 100644 src/agg_color_rgba.cpp create mode 100644 src/agg_curves.cpp create mode 100644 src/agg_embedded_raster_fonts.cpp create mode 100644 src/agg_gsv_text.cpp create mode 100644 src/agg_image_filters.cpp create mode 100644 src/agg_line_aa_basics.cpp create mode 100644 src/agg_line_profile_aa.cpp create mode 100644 src/agg_rounded_rect.cpp create mode 100644 src/agg_sqrt_tables.cpp create mode 100644 src/agg_trans_affine.cpp create mode 100644 src/agg_trans_double_path.cpp create mode 100644 src/agg_trans_single_path.cpp create mode 100644 src/agg_trans_warp_magnifier.cpp create mode 100644 src/agg_vcgen_bspline.cpp create mode 100644 src/agg_vcgen_contour.cpp create mode 100644 src/agg_vcgen_dash.cpp create mode 100644 src/agg_vcgen_markers_term.cpp create mode 100644 src/agg_vcgen_smooth_poly1.cpp create mode 100644 src/agg_vcgen_stroke.cpp create mode 100644 src/agg_vpgen_clip_polygon.cpp create mode 100644 src/agg_vpgen_clip_polyline.cpp create mode 100644 src/agg_vpgen_segmentator.cpp create mode 100644 src/ctrl/Makefile.am create mode 100644 src/ctrl/agg_bezier_ctrl.cpp create mode 100644 src/ctrl/agg_cbox_ctrl.cpp create mode 100644 src/ctrl/agg_gamma_ctrl.cpp create mode 100644 src/ctrl/agg_gamma_spline.cpp create mode 100644 src/ctrl/agg_polygon_ctrl.cpp create mode 100644 src/ctrl/agg_rbox_ctrl.cpp create mode 100644 src/ctrl/agg_scale_ctrl.cpp create mode 100644 src/ctrl/agg_slider_ctrl.cpp create mode 100644 src/ctrl/agg_spline_ctrl.cpp create mode 100644 src/platform/AmigaOS/Makefile.am create mode 100644 src/platform/AmigaOS/agg_platform_support.cpp create mode 100644 src/platform/BeOS/Makefile.am create mode 100644 src/platform/BeOS/agg_platform_support.cpp create mode 100644 src/platform/Makefile.am create mode 100644 src/platform/X11/Makefile.am create mode 100644 src/platform/X11/agg_platform_support.cpp create mode 100644 src/platform/mac/Makefile.am create mode 100644 src/platform/mac/agg_mac_pmap.cpp create mode 100644 src/platform/mac/agg_platform_support.cpp create mode 100644 src/platform/sdl/Makefile.am create mode 100644 src/platform/sdl/agg_platform_support.cpp create mode 100644 src/platform/win32/Makefile.am create mode 100644 src/platform/win32/agg_platform_support.cpp create mode 100644 src/platform/win32/agg_win32_bmp.cpp diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..a26a1cf --- /dev/null +++ b/AUTHORS @@ -0,0 +1,2 @@ +Anti-Grain Geometry - Version 2.4 +Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c5f795c --- /dev/null +++ b/CMakeLists.txt @@ -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 ) diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..9bc083f --- /dev/null +++ b/ChangeLog @@ -0,0 +1 @@ +Visit http://antigrain.com/news \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fe0fe4c --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +all: lib + +src/libagg.a: + cd src; make + +lib: src/libagg.a + +clean: + cd src; make clean diff --git a/Makefile.AmigaOS b/Makefile.AmigaOS new file mode 100644 index 0000000..3561c3a --- /dev/null +++ b/Makefile.AmigaOS @@ -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 $@ diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..f1750c1 --- /dev/null +++ b/Makefile.am @@ -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 diff --git a/Makefile.in.BeOS b/Makefile.in.BeOS new file mode 100644 index 0000000..5ecdd54 --- /dev/null +++ b/Makefile.in.BeOS @@ -0,0 +1,7 @@ +AGGLIBS= -lagg +AGGCXXFLAGS = -O1 +CXX = g++ +C = cc +LIB = ar -cru + +.PHONY : clean diff --git a/Makefile.in.CYGWIN_NT-5.0 b/Makefile.in.CYGWIN_NT-5.0 new file mode 100644 index 0000000..421e613 --- /dev/null +++ b/Makefile.in.CYGWIN_NT-5.0 @@ -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 diff --git a/Makefile.in.CYGWIN_NT-5.1 b/Makefile.in.CYGWIN_NT-5.1 new file mode 100644 index 0000000..421e613 --- /dev/null +++ b/Makefile.in.CYGWIN_NT-5.1 @@ -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 diff --git a/Makefile.in.Darwin b/Makefile.in.Darwin new file mode 100644 index 0000000..ffb35fc --- /dev/null +++ b/Makefile.in.Darwin @@ -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 diff --git a/Makefile.in.Darwin.SDL b/Makefile.in.Darwin.SDL new file mode 100644 index 0000000..c0cdcca --- /dev/null +++ b/Makefile.in.Darwin.SDL @@ -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 diff --git a/Makefile.in.IRIX64 b/Makefile.in.IRIX64 new file mode 100644 index 0000000..0440c4d --- /dev/null +++ b/Makefile.in.IRIX64 @@ -0,0 +1,7 @@ +AGGLIBS= -lagg +AGGCXXFLAGS = +CXX = CC +C = cc +LIB = CC -ar -o + +.PHONY : clean diff --git a/Makefile.in.Linux b/Makefile.in.Linux new file mode 100644 index 0000000..fa0795c --- /dev/null +++ b/Makefile.in.Linux @@ -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 diff --git a/Makefile.in.Linux.SDL b/Makefile.in.Linux.SDL new file mode 100644 index 0000000..e90b1e8 --- /dev/null +++ b/Makefile.in.Linux.SDL @@ -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 diff --git a/Makefile.in.MINGW32_NT-5.0 b/Makefile.in.MINGW32_NT-5.0 new file mode 100644 index 0000000..e1391a4 --- /dev/null +++ b/Makefile.in.MINGW32_NT-5.0 @@ -0,0 +1,8 @@ +AGGLIBS= -lagg +AGGCXXFLAGS = -O3 +CXX = g++ +C = gcc +#CXX = icc +LIB = ar cr + +.PHONY : clean diff --git a/Makefile.in.MINGW32_NT-5.1 b/Makefile.in.MINGW32_NT-5.1 new file mode 100644 index 0000000..e1391a4 --- /dev/null +++ b/Makefile.in.MINGW32_NT-5.1 @@ -0,0 +1,8 @@ +AGGLIBS= -lagg +AGGCXXFLAGS = -O3 +CXX = g++ +C = gcc +#CXX = icc +LIB = ar cr + +.PHONY : clean diff --git a/Makefile.in.SunOS b/Makefile.in.SunOS new file mode 100644 index 0000000..6166ef0 --- /dev/null +++ b/Makefile.in.SunOS @@ -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 diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..9bc083f --- /dev/null +++ b/NEWS @@ -0,0 +1 @@ +Visit http://antigrain.com/news \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..0b7f59a --- /dev/null +++ b/README @@ -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. + +--------------------------------- diff --git a/agg2d/agg2d.cpp b/agg2d/agg2d.cpp new file mode 100644 index 0000000..2ad7e40 --- /dev/null +++ b/agg2d/agg2d.cpp @@ -0,0 +1,1837 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +// +// 2007-01-25 Jerry Evans (jerry@novadsp.com) +// Ported to AGG 2.4 +// +// 2008-09-25 Jim Barry (jim@mvps.org) +// Fixed errors in kerning +// +//---------------------------------------------------------------------------- + +#include "agg2d.h" + +static const double g_approxScale = 2.0; + +Agg2D::~Agg2D() +{ +#ifndef AGG2D_USE_FREETYPE + ::ReleaseDC(0, m_fontDC); +#endif +} + +Agg2D::Agg2D() : + m_rbuf(), + m_pixFormat(m_rbuf), + m_pixFormatComp(m_rbuf), + m_pixFormatPre(m_rbuf), + m_pixFormatCompPre(m_rbuf), + m_renBase(m_pixFormat), + m_renBaseComp(m_pixFormatComp), + m_renBasePre(m_pixFormatPre), + m_renBaseCompPre(m_pixFormatCompPre), + m_renSolid(m_renBase), + m_renSolidComp(m_renBaseComp), + + m_allocator(), + m_clipBox(0,0,0,0), + + m_blendMode(BlendAlpha), + m_imageBlendMode(BlendDst), + m_imageBlendColor(0,0,0), + + m_scanline(), + m_rasterizer(), + + m_masterAlpha(1.0), + m_antiAliasGamma(1.0), + + m_fillColor(255, 255, 255), + m_lineColor(0, 0, 0), + m_fillGradient(), + m_lineGradient(), + + m_lineCap(CapRound), + m_lineJoin(JoinRound), + + m_fillGradientFlag(Solid), + m_lineGradientFlag(Solid), + m_fillGradientMatrix(), + m_lineGradientMatrix(), + m_fillGradientD1(0.0), + m_lineGradientD1(0.0), + m_fillGradientD2(100.0), + m_lineGradientD2(100.0), + + m_textAngle(0.0), + m_textAlignX(AlignLeft), + m_textAlignY(AlignBottom), + m_textHints(true), + m_fontHeight(0.0), + m_fontAscent(0.0), + m_fontDescent(0.0), + m_fontCacheType(RasterFontCache), + + m_imageFilter(Bilinear), + m_imageResample(NoResample), + m_imageFilterLut(agg::image_filter_bilinear(), true), + + m_fillGradientInterpolator(m_fillGradientMatrix), + m_lineGradientInterpolator(m_lineGradientMatrix), + + m_linearGradientFunction(), + m_radialGradientFunction(), + + m_lineWidth(1), + m_evenOddFlag(false), + + m_path(), + m_transform(), + + m_convCurve(m_path), + m_convStroke(m_convCurve), + + m_pathTransform(m_convCurve, m_transform), + m_strokeTransform(m_convStroke, m_transform), + +#ifdef AGG2D_USE_FREETYPE + m_fontEngine(), +#else + m_fontDC(::GetDC(0)), + m_fontEngine(m_fontDC), +#endif + m_fontCacheManager(m_fontEngine) +{ + lineCap(m_lineCap); + lineJoin(m_lineJoin); +} + + +//------------------------------------------------------------------------ +void Agg2D::attach(unsigned char* buf, unsigned width, unsigned height, int stride) +{ + m_rbuf.attach(buf, width, height, stride); + + m_renBase.reset_clipping(true); + m_renBaseComp.reset_clipping(true); + m_renBasePre.reset_clipping(true); + m_renBaseCompPre.reset_clipping(true); + + resetTransformations(); + lineWidth(1.0), + lineColor(0,0,0); + fillColor(255,255,255); + textAlignment(AlignLeft, AlignBottom); + clipBox(0, 0, width, height); + lineCap(CapRound); + lineJoin(JoinRound); + flipText(false); + imageFilter(Bilinear); + imageResample(NoResample); + m_masterAlpha = 1.0; + m_antiAliasGamma = 1.0; + m_rasterizer.gamma(agg::gamma_none()); + m_blendMode = BlendAlpha; +} + + +//------------------------------------------------------------------------ +void Agg2D::attach(Image& img) +{ + attach(img.renBuf.buf(), img.renBuf.width(), img.renBuf.height(), img.renBuf.stride()); +} + +//------------------------------------------------------------------------ +void Agg2D::clipBox(double x1, double y1, double x2, double y2) +{ + m_clipBox = RectD(x1, y1, x2, y2); + int rx1 = int(x1); + int ry1 = int(y1); + int rx2 = int(x2); + int ry2 = int(y2); + + m_renBase.clip_box(rx1, ry1, rx2, ry2); + m_renBaseComp.clip_box(rx1, ry1, rx2, ry2); + m_renBasePre.clip_box(rx1, ry1, rx2, ry2); + m_renBaseCompPre.clip_box(rx1, ry1, rx2, ry2); + + m_rasterizer.clip_box(x1, y1, x2, y2); +} + +//------------------------------------------------------------------------ +void Agg2D::blendMode(BlendMode m) +{ + m_blendMode = m; + m_pixFormatComp.comp_op(m); + m_pixFormatCompPre.comp_op(m); +} + +//------------------------------------------------------------------------ +Agg2D::BlendMode Agg2D::blendMode() const +{ + return m_blendMode; +} + +//------------------------------------------------------------------------ +void Agg2D::imageBlendMode(BlendMode m) +{ + m_imageBlendMode = m; +} + +//------------------------------------------------------------------------ +Agg2D::BlendMode Agg2D::imageBlendMode() const +{ + return m_imageBlendMode; +} + +//------------------------------------------------------------------------ +void Agg2D::imageBlendColor(Color c) +{ + m_imageBlendColor = c; +} + +//------------------------------------------------------------------------ +void Agg2D::imageBlendColor(unsigned r, unsigned g, unsigned b, unsigned a) +{ + imageBlendColor(Color(r, g, b, a)); +} + +//------------------------------------------------------------------------ +Agg2D::Color Agg2D::imageBlendColor() const +{ + return m_imageBlendColor; +} + +//------------------------------------------------------------------------ +void Agg2D::masterAlpha(double a) +{ + m_masterAlpha = a; + updateRasterizerGamma(); +} + +//------------------------------------------------------------------------ +double Agg2D::masterAlpha() const +{ + return m_masterAlpha; +} + +//------------------------------------------------------------------------ +void Agg2D::antiAliasGamma(double g) +{ + m_antiAliasGamma = g; + updateRasterizerGamma(); +} + +//------------------------------------------------------------------------ +double Agg2D::antiAliasGamma() const +{ + return m_antiAliasGamma; +} + +//------------------------------------------------------------------------ +Agg2D::RectD Agg2D::clipBox() const +{ + return m_clipBox; +} + +//------------------------------------------------------------------------ +void Agg2D::clearAll(Color c) +{ + m_renBase.clear(c); +} + +//------------------------------------------------------------------------ +void Agg2D::clearAll(unsigned r, unsigned g, unsigned b, unsigned a) +{ + clearAll(Color(r, g, b, a)); +} + +//------------------------------------------------------------------------ +void Agg2D::clearClipBox(Color c) +{ + m_renBase.copy_bar(0, 0, m_renBase.width(), m_renBase.height(), c); +} + +//------------------------------------------------------------------------ +void Agg2D::clearClipBox(unsigned r, unsigned g, unsigned b, unsigned a) +{ + clearClipBox(Color(r, g, b, a)); +} + +//------------------------------------------------------------------------ +void Agg2D::worldToScreen(double& x, double& y) const +{ + m_transform.transform(&x, &y); +} + +//------------------------------------------------------------------------ +void Agg2D::screenToWorld(double& x, double& y) const +{ + m_transform.inverse_transform(&x, &y); +} + + +//------------------------------------------------------------------------ +double Agg2D::worldToScreen(double scalar) const +{ + double x1 = 0; + double y1 = 0; + double x2 = scalar; + double y2 = scalar; + worldToScreen(x1, y1); + worldToScreen(x2, y2); + return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) * 0.7071068; +} + + +//------------------------------------------------------------------------ +double Agg2D::screenToWorld(double scalar) const +{ + double x1 = 0; + double y1 = 0; + double x2 = scalar; + double y2 = scalar; + screenToWorld(x1, y1); + screenToWorld(x2, y2); + return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) * 0.7071068; +} + + +//------------------------------------------------------------------------ +void Agg2D::alignPoint(double& x, double& y) const +{ + worldToScreen(x, y); + x = floor(x) + 0.5; + y = floor(y) + 0.5; + screenToWorld(x, y); +} + + +//------------------------------------------------------------------------ +bool Agg2D::inBox(double worldX, double worldY) const +{ + worldToScreen(worldX, worldY); + return m_renBase.inbox(int(worldX), int(worldY)); +} + + +//------------------------------------------------------------------------ +Agg2D::Transformations Agg2D::transformations() const +{ + Transformations tr; + m_transform.store_to(tr.affineMatrix); + return tr; +} + + +//------------------------------------------------------------------------ +void Agg2D::transformations(const Transformations& tr) +{ + m_transform.load_from(tr.affineMatrix); + m_convCurve.approximation_scale(worldToScreen(1.0) * g_approxScale); + m_convStroke.approximation_scale(worldToScreen(1.0) * g_approxScale); +} + + +//------------------------------------------------------------------------ +void Agg2D::resetTransformations() +{ + m_transform.reset(); +} + + +//------------------------------------------------------------------------ +void Agg2D::rotate(double angle) { m_transform *= agg::trans_affine_rotation(angle); } +void Agg2D::skew(double sx, double sy) { m_transform *= agg::trans_affine_skewing(sx, sy); } +void Agg2D::translate(double x, double y) { m_transform *= agg::trans_affine_translation(x, y); } + + +//------------------------------------------------------------------------ +void Agg2D::affine(const Affine& tr) +{ + m_transform *= tr; + m_convCurve.approximation_scale(worldToScreen(1.0) * g_approxScale); + m_convStroke.approximation_scale(worldToScreen(1.0) * g_approxScale); +} + +//------------------------------------------------------------------------ +void Agg2D::affine(const Transformations& tr) +{ + affine(agg::trans_affine(tr.affineMatrix[0], tr.affineMatrix[1], tr.affineMatrix[2], + tr.affineMatrix[3], tr.affineMatrix[4], tr.affineMatrix[5])); +} + +//------------------------------------------------------------------------ +void Agg2D::scale(double sx, double sy) +{ + m_transform *= agg::trans_affine_scaling(sx, sy); + m_convCurve.approximation_scale(worldToScreen(1.0) * g_approxScale); + m_convStroke.approximation_scale(worldToScreen(1.0) * g_approxScale); +} + + +//------------------------------------------------------------------------ +void Agg2D::parallelogram(double x1, double y1, double x2, double y2, const double* para) +{ + m_transform *= agg::trans_affine(x1, y1, x2, y2, para); + m_convCurve.approximation_scale(worldToScreen(1.0) * g_approxScale); + m_convStroke.approximation_scale(worldToScreen(1.0) * g_approxScale); +} + + +//------------------------------------------------------------------------ +void Agg2D::viewport(double worldX1, double worldY1, double worldX2, double worldY2, + double screenX1, double screenY1, double screenX2, double screenY2, + ViewportOption opt) +{ + agg::trans_viewport vp; + switch(opt) + { + case Anisotropic: vp.preserve_aspect_ratio(0.0, 0.0, agg::aspect_ratio_stretch); break; + case XMinYMin: vp.preserve_aspect_ratio(0.0, 0.0, agg::aspect_ratio_meet); break; + case XMidYMin: vp.preserve_aspect_ratio(0.5, 0.0, agg::aspect_ratio_meet); break; + case XMaxYMin: vp.preserve_aspect_ratio(1.0, 0.0, agg::aspect_ratio_meet); break; + case XMinYMid: vp.preserve_aspect_ratio(0.0, 0.5, agg::aspect_ratio_meet); break; + case XMidYMid: vp.preserve_aspect_ratio(0.5, 0.5, agg::aspect_ratio_meet); break; + case XMaxYMid: vp.preserve_aspect_ratio(1.0, 0.5, agg::aspect_ratio_meet); break; + case XMinYMax: vp.preserve_aspect_ratio(0.0, 1.0, agg::aspect_ratio_meet); break; + case XMidYMax: vp.preserve_aspect_ratio(0.5, 1.0, agg::aspect_ratio_meet); break; + case XMaxYMax: vp.preserve_aspect_ratio(1.0, 1.0, agg::aspect_ratio_meet); break; + } + vp.world_viewport(worldX1, worldY1, worldX2, worldY2); + vp.device_viewport(screenX1, screenY1, screenX2, screenY2); + m_transform *= vp.to_affine(); + m_convCurve.approximation_scale(worldToScreen(1.0) * g_approxScale); + m_convStroke.approximation_scale(worldToScreen(1.0) * g_approxScale); +} + + +//------------------------------------------------------------------------ +void Agg2D::fillColor(Color c) +{ + m_fillColor = c; + m_fillGradientFlag = Solid; +} + +//------------------------------------------------------------------------ +void Agg2D::fillColor(unsigned r, unsigned g, unsigned b, unsigned a) +{ + fillColor(Color(r, g, b, a)); +} + +//------------------------------------------------------------------------ +void Agg2D::noFill() +{ + fillColor(Color(0, 0, 0, 0)); +} + +//------------------------------------------------------------------------ +void Agg2D::lineColor(Color c) +{ + m_lineColor = c; + m_lineGradientFlag = Solid; +} + +//------------------------------------------------------------------------ +void Agg2D::lineColor(unsigned r, unsigned g, unsigned b, unsigned a) +{ + lineColor(Color(r, g, b, a)); +} + +//------------------------------------------------------------------------ +void Agg2D::noLine() +{ + lineColor(Color(0, 0, 0, 0)); +} + +//------------------------------------------------------------------------ +Agg2D::Color Agg2D::fillColor() const +{ + return m_fillColor; +} + +//------------------------------------------------------------------------ +Agg2D::Color Agg2D::lineColor() const +{ + return m_lineColor; +} + +//------------------------------------------------------------------------ +void Agg2D::fillLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile) +{ + int i; + int startGradient = 128 - int(profile * 127.0); + int endGradient = 128 + int(profile * 127.0); + if (endGradient <= startGradient) endGradient = startGradient + 1; + double k = 1.0 / double(endGradient - startGradient); + for (i = 0; i < startGradient; i++) + { + m_fillGradient[i] = c1; + } + for (; i < endGradient; i++) + { + m_fillGradient[i] = c1.gradient(c2, double(i - startGradient) * k); + } + for (; i < 256; i++) + { + m_fillGradient[i] = c2; + } + double angle = atan2(y2-y1, x2-x1); + m_fillGradientMatrix.reset(); + m_fillGradientMatrix *= agg::trans_affine_rotation(angle); + m_fillGradientMatrix *= agg::trans_affine_translation(x1, y1); + m_fillGradientMatrix *= m_transform; + m_fillGradientMatrix.invert(); + m_fillGradientD1 = 0.0; + m_fillGradientD2 = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)); + m_fillGradientFlag = Linear; + m_fillColor = Color(0,0,0); // Set some real color +} + + +//------------------------------------------------------------------------ +void Agg2D::lineLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile) +{ + int i; + int startGradient = 128 - int(profile * 128.0); + int endGradient = 128 + int(profile * 128.0); + if (endGradient <= startGradient) endGradient = startGradient + 1; + double k = 1.0 / double(endGradient - startGradient); + for (i = 0; i < startGradient; i++) + { + m_lineGradient[i] = c1; + } + for (; i < endGradient; i++) + { + m_lineGradient[i] = c1.gradient(c2, double(i - startGradient) * k); + } + for (; i < 256; i++) + { + m_lineGradient[i] = c2; + } + double angle = atan2(y2-y1, x2-x1); + m_lineGradientMatrix.reset(); + m_lineGradientMatrix *= agg::trans_affine_rotation(angle); + m_lineGradientMatrix *= agg::trans_affine_translation(x1, y1); + m_fillGradientMatrix *= m_transform; + m_lineGradientMatrix.invert(); + m_lineGradientD1 = 0; + m_lineGradientD2 = sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1)); + m_lineGradientFlag = Linear; + m_lineColor = Color(0,0,0); // Set some real color +} + + +//------------------------------------------------------------------------ +void Agg2D::fillRadialGradient(double x, double y, double r, Color c1, Color c2, double profile) +{ + int i; + int startGradient = 128 - int(profile * 127.0); + int endGradient = 128 + int(profile * 127.0); + if (endGradient <= startGradient) endGradient = startGradient + 1; + double k = 1.0 / double(endGradient - startGradient); + for (i = 0; i < startGradient; i++) + { + m_fillGradient[i] = c1; + } + for (; i < endGradient; i++) + { + m_fillGradient[i] = c1.gradient(c2, double(i - startGradient) * k); + } + for (; i < 256; i++) + { + m_fillGradient[i] = c2; + } + m_fillGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_fillGradientMatrix.reset(); + m_fillGradientMatrix *= agg::trans_affine_translation(x, y); + m_fillGradientMatrix.invert(); + m_fillGradientD1 = 0; + m_fillGradientFlag = Radial; + m_fillColor = Color(0,0,0); // Set some real color +} + + +//------------------------------------------------------------------------ +void Agg2D::lineRadialGradient(double x, double y, double r, Color c1, Color c2, double profile) +{ + int i; + int startGradient = 128 - int(profile * 128.0); + int endGradient = 128 + int(profile * 128.0); + if (endGradient <= startGradient) endGradient = startGradient + 1; + double k = 1.0 / double(endGradient - startGradient); + for (i = 0; i < startGradient; i++) + { + m_lineGradient[i] = c1; + } + for (; i < endGradient; i++) + { + m_lineGradient[i] = c1.gradient(c2, double(i - startGradient) * k); + } + for (; i < 256; i++) + { + m_lineGradient[i] = c2; + } + m_lineGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_lineGradientMatrix.reset(); + m_lineGradientMatrix *= agg::trans_affine_translation(x, y); + m_lineGradientMatrix.invert(); + m_lineGradientD1 = 0; + m_lineGradientFlag = Radial; + m_lineColor = Color(0,0,0); // Set some real color +} + + +//------------------------------------------------------------------------ +void Agg2D::fillRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3) +{ + int i; + for (i = 0; i < 128; i++) + { + m_fillGradient[i] = c1.gradient(c2, double(i) / 127.0); + } + for (; i < 256; i++) + { + m_fillGradient[i] = c2.gradient(c3, double(i - 128) / 127.0); + } + m_fillGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_fillGradientMatrix.reset(); + m_fillGradientMatrix *= agg::trans_affine_translation(x, y); + m_fillGradientMatrix.invert(); + m_fillGradientD1 = 0; + m_fillGradientFlag = Radial; + m_fillColor = Color(0,0,0); // Set some real color +} + + +//------------------------------------------------------------------------ +void Agg2D::lineRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3) +{ + int i; + for (i = 0; i < 128; i++) + { + m_lineGradient[i] = c1.gradient(c2, double(i) / 127.0); + } + for (; i < 256; i++) + { + m_lineGradient[i] = c2.gradient(c3, double(i - 128) / 127.0); + } + m_lineGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_lineGradientMatrix.reset(); + m_lineGradientMatrix *= agg::trans_affine_translation(x, y); + m_lineGradientMatrix.invert(); + m_lineGradientD1 = 0; + m_lineGradientFlag = Radial; + m_lineColor = Color(0,0,0); // Set some real color +} + + +void Agg2D::fillRadialGradient(double x, double y, double r) +{ + m_fillGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_fillGradientMatrix.reset(); + m_fillGradientMatrix *= agg::trans_affine_translation(x, y); + m_fillGradientMatrix.invert(); + m_fillGradientD1 = 0; +} + + +//------------------------------------------------------------------------ +void Agg2D::lineRadialGradient(double x, double y, double r) +{ + m_lineGradientD2 = worldToScreen(r); + worldToScreen(x, y); + m_lineGradientMatrix.reset(); + m_lineGradientMatrix *= agg::trans_affine_translation(x, y); + m_lineGradientMatrix.invert(); + m_lineGradientD1 = 0; +} + + +//------------------------------------------------------------------------ +void Agg2D::lineWidth(double w) +{ + m_lineWidth = w; + m_convStroke.width(w); +} + + +//------------------------------------------------------------------------ +double Agg2D::lineWidth(double w) const +{ + return m_lineWidth; +} + + +//------------------------------------------------------------------------ +void Agg2D::fillEvenOdd(bool evenOddFlag) +{ + m_evenOddFlag = evenOddFlag; + m_rasterizer.filling_rule(evenOddFlag ? agg::fill_even_odd : agg::fill_non_zero); +} + + +//------------------------------------------------------------------------ +bool Agg2D::fillEvenOdd() const +{ + return m_evenOddFlag; +} + + +//------------------------------------------------------------------------ +void Agg2D::lineCap(LineCap cap) +{ + m_lineCap = cap; + m_convStroke.line_cap((agg::line_cap_e)cap); +} + + +//------------------------------------------------------------------------ +Agg2D::LineCap Agg2D::lineCap() const +{ + return m_lineCap; +} + + +//------------------------------------------------------------------------ +void Agg2D::lineJoin(LineJoin join) +{ + m_lineJoin = join; + m_convStroke.line_join((agg::line_join_e)join); +} + + +//------------------------------------------------------------------------ +Agg2D::LineJoin Agg2D::lineJoin() const +{ + return m_lineJoin; +} + + +//------------------------------------------------------------------------ +void Agg2D::addLine(double x1, double y1, double x2, double y2) +{ + m_path.move_to(x1, y1); + m_path.line_to(x2, y2); +} + + +//------------------------------------------------------------------------ +void Agg2D::line(double x1, double y1, double x2, double y2) +{ + m_path.remove_all(); + addLine(x1, y1, x2, y2); + drawPath(StrokeOnly); +} + + +//------------------------------------------------------------------------ +void Agg2D::triangle(double x1, double y1, double x2, double y2, double x3, double y3) +{ + m_path.remove_all(); + m_path.move_to(x1, y1); + m_path.line_to(x2, y2); + m_path.line_to(x3, y3); + m_path.close_polygon(); + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +void Agg2D::rectangle(double x1, double y1, double x2, double y2) +{ + m_path.remove_all(); + m_path.move_to(x1, y1); + m_path.line_to(x2, y1); + m_path.line_to(x2, y2); + m_path.line_to(x1, y2); + m_path.close_polygon(); + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +void Agg2D::roundedRect(double x1, double y1, double x2, double y2, double r) +{ + m_path.remove_all(); + agg::rounded_rect rc(x1, y1, x2, y2, r); + rc.normalize_radius(); + rc.approximation_scale(worldToScreen(1.0) * g_approxScale); + // JME audit + //m_path.add_path(rc, 0, false); + m_path.concat_path(rc,0); + drawPath(FillAndStroke); +} + + + +//------------------------------------------------------------------------ +void Agg2D::roundedRect(double x1, double y1, double x2, double y2, double rx, double ry) +{ + m_path.remove_all(); + agg::rounded_rect rc; + rc.rect(x1, y1, x2, y2); + rc.radius(rx, ry); + rc.normalize_radius(); + //m_path.add_path(rc, 0, false); + m_path.concat_path(rc,0); // JME + drawPath(FillAndStroke); +} + + + +//------------------------------------------------------------------------ +void Agg2D::roundedRect(double x1, double y1, double x2, double y2, + double rx_bottom, double ry_bottom, + double rx_top, double ry_top) +{ + m_path.remove_all(); + agg::rounded_rect rc; + rc.rect(x1, y1, x2, y2); + rc.radius(rx_bottom, ry_bottom, rx_top, ry_top); + rc.normalize_radius(); + rc.approximation_scale(worldToScreen(1.0) * g_approxScale); + //m_path.add_path(rc, 0, false); + m_path.concat_path(rc,0); // JME + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +void Agg2D::ellipse(double cx, double cy, double rx, double ry) +{ + m_path.remove_all(); + agg::bezier_arc arc(cx, cy, rx, ry, 0, 2*pi()); + //m_path.add_path(arc, 0, false); + m_path.concat_path(arc,0); // JME + m_path.close_polygon(); + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +void Agg2D::arc(double cx, double cy, double rx, double ry, double start, double sweep) +{ + m_path.remove_all(); + agg::bezier_arc arc(cx, cy, rx, ry, start, sweep); + //m_path.add_path(arc, 0, false); + m_path.concat_path(arc,0); // JME + drawPath(StrokeOnly); +} + + +//------------------------------------------------------------------------ +void Agg2D::star(double cx, double cy, double r1, double r2, double startAngle, int numRays) +{ + m_path.remove_all(); + double da = agg::pi / double(numRays); + double a = startAngle; + int i; + for (i = 0; i < numRays; i++) + { + double x = cos(a) * r2 + cx; + double y = sin(a) * r2 + cy; + if (i) m_path.line_to(x, y); + else m_path.move_to(x, y); + a += da; + m_path.line_to(cos(a) * r1 + cx, sin(a) * r1 + cy); + a += da; + } + closePolygon(); + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +void Agg2D::curve(double x1, double y1, double x2, double y2, double x3, double y3) +{ + m_path.remove_all(); + m_path.move_to(x1, y1); + m_path.curve3(x2, y2, x3, y3); + drawPath(StrokeOnly); +} + + +//------------------------------------------------------------------------ +void Agg2D::curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4) +{ + m_path.remove_all(); + m_path.move_to(x1, y1); + m_path.curve4(x2, y2, x3, y3, x4, y4); + drawPath(StrokeOnly); +} + + +//------------------------------------------------------------------------ +void Agg2D::polygon(double* xy, int numPoints) +{ + m_path.remove_all(); + //m_path.add_poly(xy, numPoints); + m_path.concat_poly(xy,0,true); // JME + closePolygon(); + drawPath(FillAndStroke); +} + + +//------------------------------------------------------------------------ +void Agg2D::polyline(double* xy, int numPoints) +{ + m_path.remove_all(); + //m_path.add_poly(xy, numPoints); + m_path.concat_poly(xy,0,true); // JME + drawPath(StrokeOnly); +} + + +//------------------------------------------------------------------------ +void Agg2D::flipText(bool flip) +{ + m_fontEngine.flip_y(flip); +} + +//------------------------------------------------------------------------ +void Agg2D::font(const char* fontName, + double height, + bool bold, + bool italic, + FontCacheType ch, + double angle) +{ + m_textAngle = angle; + m_fontHeight = height; + m_fontCacheType = ch; + +#ifdef AGG2D_USE_FREETYPE + m_fontEngine.load_font(fontName, + 0, + (ch == VectorFontCache) ? + agg::glyph_ren_outline : + agg::glyph_ren_agg_gray8); + m_fontEngine.hinting(m_textHints); + m_fontEngine.height((ch == VectorFontCache) ? height : worldToScreen(height)); +#else + m_fontEngine.hinting(m_textHints); + + m_fontEngine.create_font(fontName, + (ch == VectorFontCache) ? + agg::glyph_ren_outline : + agg::glyph_ren_agg_gray8, + (ch == VectorFontCache) ? height : worldToScreen(height), + 0.0, + bold ? 700 : 400, + italic); +#endif +} + + +//------------------------------------------------------------------------ +double Agg2D::fontHeight() const +{ + return m_fontHeight; +} + +//------------------------------------------------------------------------ +void Agg2D::textAlignment(TextAlignment alignX, TextAlignment alignY) +{ + m_textAlignX = alignX; + m_textAlignY = alignY; +} + +//------------------------------------------------------------------------ +double Agg2D::textWidth(const char* str) +{ + double x = 0; + double y = 0; + bool first = true; + while(*str) + { + const agg::glyph_cache* glyph = m_fontCacheManager.glyph(*str); + if(glyph) + { + if(!first) m_fontCacheManager.add_kerning(&x, &y); + x += glyph->advance_x; + y += glyph->advance_y; + first = false; + } + ++str; + } + return (m_fontCacheType == VectorFontCache) ? x : screenToWorld(x); +} + +//------------------------------------------------------------------------ +bool Agg2D::textHints() const +{ + return m_textHints; +} + +//------------------------------------------------------------------------ +void Agg2D::textHints(bool hints) +{ + m_textHints = hints; +} + + + +//------------------------------------------------------------------------ +void Agg2D::text(double x, double y, const char* str, bool roundOff, double ddx, double ddy) +{ + double dx = 0.0; + double dy = 0.0; + + switch(m_textAlignX) + { + case AlignCenter: dx = -textWidth(str) * 0.5; break; + case AlignRight: dx = -textWidth(str); break; + default: break; + } + + + double asc = fontHeight(); + const agg::glyph_cache* glyph = m_fontCacheManager.glyph('H'); + if(glyph) + { + asc = glyph->bounds.y2 - glyph->bounds.y1; + } + + if(m_fontCacheType == RasterFontCache) + { + asc = screenToWorld(asc); + } + + switch(m_textAlignY) + { + case AlignCenter: dy = -asc * 0.5; break; + case AlignTop: dy = -asc; break; + default: break; + } + + if(m_fontEngine.flip_y()) dy = -dy; + + agg::trans_affine mtx; + + double start_x = x + dx; + double start_y = y + dy; + + if (roundOff) + { + start_x = int(start_x); + start_y = int(start_y); + } + start_x += ddx; + start_y += ddy; + + mtx *= agg::trans_affine_translation(-x, -y); + mtx *= agg::trans_affine_rotation(m_textAngle); + mtx *= agg::trans_affine_translation(x, y); + + agg::conv_transform tr(m_fontCacheManager.path_adaptor(), mtx); + + if(m_fontCacheType == RasterFontCache) + { + worldToScreen(start_x, start_y); + } + + int i; + for (i = 0; str[i]; i++) + { + glyph = m_fontCacheManager.glyph(str[i]); + if(glyph) + { + if(i) m_fontCacheManager.add_kerning(&start_x, &start_y); + m_fontCacheManager.init_embedded_adaptors(glyph, start_x, start_y); + + if(glyph->data_type == agg::glyph_data_outline) + { + m_path.remove_all(); + //m_path.add_path(tr, 0, false); + m_path.concat_path(tr,0); // JME + drawPath(); + } + + if(glyph->data_type == agg::glyph_data_gray8) + { + render(m_fontCacheManager.gray8_adaptor(), + m_fontCacheManager.gray8_scanline()); + } + start_x += glyph->advance_x; + start_y += glyph->advance_y; + } + } +} + +//------------------------------------------------------------------------ +void Agg2D::resetPath() { m_path.remove_all(); } + +//------------------------------------------------------------------------ +void Agg2D::moveTo(double x, double y) +{ + m_path.move_to(x, y); +} + +//------------------------------------------------------------------------ +void Agg2D::moveRel(double dx, double dy) +{ + m_path.move_rel(dx, dy); +} + + +//------------------------------------------------------------------------ +void Agg2D::lineTo(double x, double y) +{ + m_path.line_to(x, y); +} + + +//------------------------------------------------------------------------ +void Agg2D::lineRel(double dx, double dy) +{ + m_path.line_rel(dx, dy); +} + + +//------------------------------------------------------------------------ +void Agg2D::horLineTo(double x) +{ + m_path.hline_to(x); +} + + +//------------------------------------------------------------------------ +void Agg2D::horLineRel(double dx) +{ + m_path.hline_rel(dx); +} + + +//------------------------------------------------------------------------ +void Agg2D::verLineTo(double y) +{ + m_path.vline_to(y); +} + + +//------------------------------------------------------------------------ +void Agg2D::verLineRel(double dy) +{ + m_path.vline_rel(dy); +} + + +//------------------------------------------------------------------------ +void Agg2D::arcTo(double rx, double ry, + double angle, + bool largeArcFlag, + bool sweepFlag, + double x, double y) +{ + m_path.arc_to(rx, ry, angle, largeArcFlag, sweepFlag, x, y); +} + + +//------------------------------------------------------------------------ +void Agg2D::arcRel(double rx, double ry, + double angle, + bool largeArcFlag, + bool sweepFlag, + double dx, double dy) +{ + m_path.arc_rel(rx, ry, angle, largeArcFlag, sweepFlag, dx, dy); +} + + +//------------------------------------------------------------------------ +void Agg2D::quadricCurveTo(double xCtrl, double yCtrl, + double xTo, double yTo) +{ + m_path.curve3(xCtrl, yCtrl, xTo, yTo); +} + + +//------------------------------------------------------------------------ +void Agg2D::quadricCurveRel(double dxCtrl, double dyCtrl, + double dxTo, double dyTo) +{ + m_path.curve3_rel(dxCtrl, dyCtrl, dxTo, dyTo); +} + + +//------------------------------------------------------------------------ +void Agg2D::quadricCurveTo(double xTo, double yTo) +{ + m_path.curve3(xTo, yTo); +} + + +//------------------------------------------------------------------------ +void Agg2D::quadricCurveRel(double dxTo, double dyTo) +{ + m_path.curve3_rel(dxTo, dyTo); +} + + +//------------------------------------------------------------------------ +void Agg2D::cubicCurveTo(double xCtrl1, double yCtrl1, + double xCtrl2, double yCtrl2, + double xTo, double yTo) +{ + m_path.curve4(xCtrl1, yCtrl1, xCtrl2, yCtrl2, xTo, yTo); +} + + +//------------------------------------------------------------------------ +void Agg2D::cubicCurveRel(double dxCtrl1, double dyCtrl1, + double dxCtrl2, double dyCtrl2, + double dxTo, double dyTo) +{ + m_path.curve4_rel(dxCtrl1, dyCtrl1, dxCtrl2, dyCtrl2, dxTo, dyTo); +} + + +//------------------------------------------------------------------------ +void Agg2D::cubicCurveTo(double xCtrl2, double yCtrl2, + double xTo, double yTo) +{ + m_path.curve4(xCtrl2, yCtrl2, xTo, yTo); +} + + +//------------------------------------------------------------------------ +void Agg2D::cubicCurveRel(double xCtrl2, double yCtrl2, + double xTo, double yTo) +{ + m_path.curve4_rel(xCtrl2, yCtrl2, xTo, yTo); +} + +//------------------------------------------------------------------------ +void Agg2D::addEllipse(double cx, double cy, double rx, double ry, Direction dir) +{ + agg::bezier_arc arc(cx, cy, rx, ry, 0, (dir == CCW) ? 2*pi() : -2*pi()); + //m_path.add_path(arc, 0, false); + m_path.concat_path(arc,0); // JME + m_path.close_polygon(); +} + +//------------------------------------------------------------------------ +void Agg2D::closePolygon() +{ + m_path.close_polygon(); +} + + +//------------------------------------------------------------------------ +void Agg2D::imageFilter(ImageFilter f) +{ + m_imageFilter = f; + switch(f) + { + case NoFilter: break; + case Bilinear: m_imageFilterLut.calculate(agg::image_filter_bilinear(), true); break; + case Hanning: m_imageFilterLut.calculate(agg::image_filter_hanning(), true); break; + case Hermite: m_imageFilterLut.calculate(agg::image_filter_hermite(), true); break; + case Quadric: m_imageFilterLut.calculate(agg::image_filter_quadric(), true); break; + case Bicubic: m_imageFilterLut.calculate(agg::image_filter_bicubic(), true); break; + case Catrom: m_imageFilterLut.calculate(agg::image_filter_catrom(), true); break; + case Spline16: m_imageFilterLut.calculate(agg::image_filter_spline16(), true); break; + case Spline36: m_imageFilterLut.calculate(agg::image_filter_spline36(), true); break; + case Blackman144: m_imageFilterLut.calculate(agg::image_filter_blackman144(), true); break; + } +} + + +//------------------------------------------------------------------------ +Agg2D::ImageFilter Agg2D::imageFilter() const +{ + return m_imageFilter; +} + + +//------------------------------------------------------------------------ +void Agg2D::imageResample(ImageResample f) +{ + m_imageResample = f; +} + + +//------------------------------------------------------------------------ +Agg2D::ImageResample Agg2D::imageResample() const +{ + return m_imageResample; +} + + +//------------------------------------------------------------------------ +void Agg2D::transformImage(const Image& img, int imgX1, int imgY1, int imgX2, int imgY2, + double dstX1, double dstY1, double dstX2, double dstY2) +{ + resetPath(); + moveTo(dstX1, dstY1); + lineTo(dstX2, dstY1); + lineTo(dstX2, dstY2); + lineTo(dstX1, dstY2); + closePolygon(); + double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; + renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); +} + +//------------------------------------------------------------------------ +void Agg2D::transformImage(const Image& img, double dstX1, double dstY1, double dstX2, double dstY2) +{ + resetPath(); + moveTo(dstX1, dstY1); + lineTo(dstX2, dstY1); + lineTo(dstX2, dstY2); + lineTo(dstX1, dstY2); + closePolygon(); + double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); +} + +//------------------------------------------------------------------------ +void Agg2D::transformImage(const Image& img, int imgX1, int imgY1, int imgX2, int imgY2, + const double* parallelogram) +{ + resetPath(); + moveTo(parallelogram[0], parallelogram[1]); + lineTo(parallelogram[2], parallelogram[3]); + lineTo(parallelogram[4], parallelogram[5]); + lineTo(parallelogram[0] + parallelogram[4] - parallelogram[2], + parallelogram[1] + parallelogram[5] - parallelogram[3]); + closePolygon(); + renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); +} + + +//------------------------------------------------------------------------ +void Agg2D::transformImage(const Image& img, const double* parallelogram) +{ + resetPath(); + moveTo(parallelogram[0], parallelogram[1]); + lineTo(parallelogram[2], parallelogram[3]); + lineTo(parallelogram[4], parallelogram[5]); + lineTo(parallelogram[0] + parallelogram[4] - parallelogram[2], + parallelogram[1] + parallelogram[5] - parallelogram[3]); + closePolygon(); + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); +} + +//------------------------------------------------------------------------ +void Agg2D::transformImagePath(const Image& img, int imgX1, int imgY1, int imgX2, int imgY2, + double dstX1, double dstY1, double dstX2, double dstY2) +{ + double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; + renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); +} + +//------------------------------------------------------------------------ +void Agg2D::transformImagePath(const Image& img, double dstX1, double dstY1, double dstX2, double dstY2) +{ + double parallelogram[6] = { dstX1, dstY1, dstX2, dstY1, dstX2, dstY2 }; + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); +} + +//------------------------------------------------------------------------ +void Agg2D::transformImagePath(const Image& img, int imgX1, int imgY1, int imgX2, int imgY2, + const double* parallelogram) +{ + renderImage(img, imgX1, imgY1, imgX2, imgY2, parallelogram); +} + +//------------------------------------------------------------------------ +void Agg2D::transformImagePath(const Image& img, const double* parallelogram) +{ + renderImage(img, 0, 0, img.renBuf.width(), img.renBuf.height(), parallelogram); +} + + + +//------------------------------------------------------------------------ +void Agg2D::drawPath(DrawPathFlag flag) +{ + m_rasterizer.reset(); + switch(flag) + { + case FillOnly: + if (m_fillColor.a) + { + m_rasterizer.add_path(m_pathTransform); + render(true); + } + break; + + case StrokeOnly: + if (m_lineColor.a && m_lineWidth > 0.0) + { + m_rasterizer.add_path(m_strokeTransform); + render(false); + } + break; + + case FillAndStroke: + if (m_fillColor.a) + { + m_rasterizer.add_path(m_pathTransform); + render(true); + } + + if (m_lineColor.a && m_lineWidth > 0.0) + { + m_rasterizer.add_path(m_strokeTransform); + render(false); + } + break; + + case FillWithLineColor: + if (m_lineColor.a) + { + m_rasterizer.add_path(m_pathTransform); + render(false); + } + break; + } +} + + + +//------------------------------------------------------------------------ +class Agg2DRenderer +{ +public: + //-------------------------------------------------------------------- + template + void static render(Agg2D& gr, BaseRenderer& renBase, SolidRenderer& renSolid, bool fillColor) + { + // JME + typedef agg::span_allocator span_allocator_type; + //- typedef agg::renderer_scanline_aa RendererLinearGradient; + typedef agg::renderer_scanline_aa RendererLinearGradient; + //- typedef agg::renderer_scanline_aa RendererRadialGradient; + typedef agg::renderer_scanline_aa RendererRadialGradient; + + if ((fillColor && gr.m_fillGradientFlag == Agg2D::Linear) || + (!fillColor && gr.m_lineGradientFlag == Agg2D::Linear)) + { + if (fillColor) + { + Agg2D::LinearGradientSpan span(/*gr.m_allocator, */ + gr.m_fillGradientInterpolator, + gr.m_linearGradientFunction, + gr.m_fillGradient, + gr.m_fillGradientD1, + gr.m_fillGradientD2); + //-RendererLinearGradient ren(renBase,span); + RendererLinearGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ren); + } + else + { + Agg2D::LinearGradientSpan span(/*gr.m_allocator,*/ + gr.m_lineGradientInterpolator, + gr.m_linearGradientFunction, + gr.m_lineGradient, + gr.m_lineGradientD1, + gr.m_lineGradientD2); + //- RendererLinearGradient ren(renBase, span); + RendererLinearGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ren); + } + } + else + { + if ((fillColor && gr.m_fillGradientFlag == Agg2D::Radial) || + (!fillColor && gr.m_lineGradientFlag == Agg2D::Radial)) + { + if (fillColor) + { + Agg2D::RadialGradientSpan span(/*gr.m_allocator, */ + gr.m_fillGradientInterpolator, + gr.m_radialGradientFunction, + gr.m_fillGradient, + gr.m_fillGradientD1, + gr.m_fillGradientD2); + //-RendererRadialGradient ren(renBase, span); + RendererRadialGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ren); + } + else + { + Agg2D::RadialGradientSpan span(/*gr.m_allocator,*/ + gr.m_lineGradientInterpolator, + gr.m_radialGradientFunction, + gr.m_lineGradient, + gr.m_lineGradientD1, + gr.m_lineGradientD2); + //-RendererRadialGradient ren(renBase, span); + RendererRadialGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ren); + } + } + else + { + renSolid.color(fillColor ? gr.m_fillColor : gr.m_lineColor); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, renSolid); + } + } + } + + + //-------------------------------------------------------------------- + class SpanConvImageBlend + { + public: + SpanConvImageBlend(Agg2D::BlendMode m, Agg2D::Color c) : + m_mode(m), m_color(c) + {} + + void convert(Agg2D::Color* span, int x, int y, unsigned len) const + { + unsigned l2; + Agg2D::Color* s2; + if(m_mode != Agg2D::BlendDst) + { + l2 = len; + s2 = span; + typedef agg::comp_op_adaptor_clip_to_dst_rgba_pre OpType; + do + { + OpType::blend_pix(m_mode, + (Agg2D::Color::value_type*)s2, + m_color.r, + m_color.g, + m_color.b, + Agg2D::Color::full_value(), + agg::cover_full); + ++s2; + } + while(--l2); + } + if(!m_color.is_opaque()) + { + l2 = len; + s2 = span; + do + { + s2->r = Agg2D::Color::multiply(s2->r, m_color.a); + s2->g = Agg2D::Color::multiply(s2->g, m_color.a); + s2->b = Agg2D::Color::multiply(s2->b, m_color.a); + s2->a = Agg2D::Color::multiply(s2->a, m_color.a); + ++s2; + } + while(--l2); + } + } + + private: + Agg2D::BlendMode m_mode; + Agg2D::Color m_color; + }; + + + + + //-------------------------------------------------------------------- + template + void static render(Agg2D& gr, BaseRenderer& renBase, SolidRenderer& renSolid, Rasterizer& ras, Scanline& sl) + { + // JME + typedef agg::span_allocator span_allocator_type; + typedef agg::renderer_scanline_aa RendererLinearGradient; + typedef agg::renderer_scanline_aa RendererRadialGradient; + + if(gr.m_fillGradientFlag == Agg2D::Linear) + { + Agg2D::LinearGradientSpan span( + gr.m_fillGradientInterpolator, + gr.m_linearGradientFunction, + gr.m_fillGradient, + gr.m_fillGradientD1, + gr.m_fillGradientD2); + RendererLinearGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(ras, sl, ren); + } + else + { + if(gr.m_fillGradientFlag == Agg2D::Radial) + { + Agg2D::RadialGradientSpan span( + gr.m_fillGradientInterpolator, + gr.m_radialGradientFunction, + gr.m_fillGradient, + gr.m_fillGradientD1, + gr.m_fillGradientD2); + RendererRadialGradient ren(renBase,gr.m_allocator,span); + agg::render_scanlines(ras, sl, ren); + } + else + { + renSolid.color(gr.m_fillColor); + agg::render_scanlines(ras, sl, renSolid); + } + } + } + + + + //-------------------------------------------------------------------- + //! JME - this is where the bulk of the changes have taken place. + template + static void renderImage(Agg2D& gr, const Agg2D::Image& img, + BaseRenderer& renBase, Interpolator& interpolator) + { + //! JME - have not quite figured which part of this is not const-correct + // hence the cast. + Agg2D::Image& imgc = const_cast(img); + Agg2D::PixFormat img_pixf(imgc.renBuf); + typedef agg::image_accessor_clone img_source_type; + img_source_type source(img_pixf); + + SpanConvImageBlend blend(gr.m_imageBlendMode, gr.m_imageBlendColor); + if (gr.m_imageFilter == Agg2D::NoFilter) + { + + typedef agg::span_image_filter_rgba_nn SpanGenType; + typedef agg::span_converter SpanConvType; + typedef agg::renderer_scanline_aa RendererType; + + SpanGenType sg(source,interpolator); + SpanConvType sc(sg, blend); + RendererType ri(renBase,gr.m_allocator,sg); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + } + else + { + bool resample = (gr.m_imageResample == Agg2D::ResampleAlways); + if(gr.m_imageResample == Agg2D::ResampleOnZoomOut) + { + double sx, sy; + interpolator.transformer().scaling_abs(&sx,&sy); + if (sx > 1.125 || sy > 1.125) + { + resample = true; + } + } + + if (resample) + { + typedef agg::span_image_resample_rgba_affine SpanGenType; + typedef agg::span_converter SpanConvType; + typedef agg::renderer_scanline_aa RendererType; + + SpanGenType sg(source,interpolator,gr.m_imageFilterLut); + SpanConvType sc(sg, blend); + RendererType ri(renBase,gr.m_allocator,sg); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + } + else + { + // this is the AGG2D default + if (gr.m_imageFilter == Agg2D::Bilinear) + { + typedef agg::span_image_filter_rgba_bilinear SpanGenType; + typedef agg::span_converter SpanConvType; + typedef agg::renderer_scanline_aa RendererType; + + SpanGenType sg(source,interpolator); + SpanConvType sc(sg, blend); + RendererType ri(renBase,gr.m_allocator,sg); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + } + else + { + if(gr.m_imageFilterLut.diameter() == 2) + { + typedef agg::span_image_filter_rgba_2x2 SpanGenType; + typedef agg::span_converter SpanConvType; + typedef agg::renderer_scanline_aa RendererType; + + SpanGenType sg(source,interpolator,gr.m_imageFilterLut); + SpanConvType sc(sg,blend); + RendererType ri(renBase,gr.m_allocator,sg); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + } + else + { + typedef agg::span_image_filter_rgba SpanGenType; + typedef agg::span_converter SpanConvType; + typedef agg::renderer_scanline_aa RendererType; + SpanGenType sg(source,interpolator,gr.m_imageFilterLut); + SpanConvType sc(sg, blend); + RendererType ri(renBase,gr.m_allocator,sg); + agg::render_scanlines(gr.m_rasterizer, gr.m_scanline, ri); + } + } + } + } + } +}; + + +//------------------------------------------------------------------------ +void Agg2D::render(bool fillColor) +{ + if(m_blendMode == BlendAlpha) + { + Agg2DRenderer::render(*this, m_renBase, m_renSolid, fillColor); + } + else + { + Agg2DRenderer::render(*this, m_renBaseComp, m_renSolidComp, fillColor); + } +} + +//------------------------------------------------------------------------ +void Agg2D::render(FontRasterizer& ras, FontScanline& sl) +{ + if(m_blendMode == BlendAlpha) + { + Agg2DRenderer::render(*this, m_renBase, m_renSolid, ras, sl); + } + else + { + Agg2DRenderer::render(*this, m_renBaseComp, m_renSolidComp, ras, sl); + } +} + +//------------------------------------------------------------------------ +void Agg2D::renderImage(const Image& img, int x1, int y1, int x2, int y2, + const double* parl) +{ + agg::trans_affine mtx((double)x1, + (double)y1, + (double)x2, + (double)y2, + parl); + mtx *= m_transform; + mtx.invert(); + + m_rasterizer.reset(); + m_rasterizer.add_path(m_pathTransform); + + typedef agg::span_interpolator_linear Interpolator; + Interpolator interpolator(mtx); + + if(m_blendMode == BlendAlpha) + { + // JME audit - + Agg2DRenderer::renderImage(*this,img, m_renBasePre, interpolator); + } + else + { + Agg2DRenderer::renderImage(*this,img, m_renBaseCompPre, interpolator); + } +} + +//------------------------------------------------------------------------ +struct Agg2DRasterizerGamma +{ + + Agg2DRasterizerGamma(double alpha, double gamma) : + m_alpha(alpha), m_gamma(gamma) {} + + double operator() (double x) const + { + return m_alpha(m_gamma(x)); + } + agg::gamma_multiply m_alpha; + agg::gamma_power m_gamma; +}; + +//------------------------------------------------------------------------ +void Agg2D::updateRasterizerGamma() +{ + m_rasterizer.gamma(Agg2DRasterizerGamma(m_masterAlpha, m_antiAliasGamma)); +} + +//------------------------------------------------------------------------ +void Agg2D::blendImage(Image& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX, double dstY, unsigned alpha) +{ + worldToScreen(dstX, dstY); + PixFormat pixF(img.renBuf); + // JME + //agg::rect r(imgX1, imgY1, imgX2, imgY2); + Rect r(imgX1, imgY1, imgX2, imgY2); + if(m_blendMode == BlendAlpha) + { + m_renBasePre.blend_from(pixF, &r, int(dstX)-imgX1, int(dstY)-imgY1, alpha); + } + else + { + m_renBaseCompPre.blend_from(pixF, &r, int(dstX)-imgX1, int(dstY)-imgY1, alpha); + } +} + + +//------------------------------------------------------------------------ +void Agg2D::blendImage(Image& img, double dstX, double dstY, unsigned alpha) +{ + worldToScreen(dstX, dstY); + PixFormat pixF(img.renBuf); + m_renBasePre.blend_from(pixF, 0, int(dstX), int(dstY), alpha); + if(m_blendMode == BlendAlpha) + { + m_renBasePre.blend_from(pixF, 0, int(dstX), int(dstY), alpha); + } + else + { + m_renBaseCompPre.blend_from(pixF, 0, int(dstX), int(dstY), alpha); + } +} + + +//------------------------------------------------------------------------ +void Agg2D::copyImage(Image& img, + int imgX1, int imgY1, int imgX2, int imgY2, + double dstX, double dstY) +{ + worldToScreen(dstX, dstY); + // JME + //agg::rect r(imgX1, imgY1, imgX2, imgY2); + Rect r(imgX1, imgY1, imgX2, imgY2); + m_renBase.copy_from(img.renBuf, &r, int(dstX)-imgX1, int(dstY)-imgY1); +} + +//------------------------------------------------------------------------ +void Agg2D::copyImage(Image& img, double dstX, double dstY) +{ + worldToScreen(dstX, dstY); + m_renBase.copy_from(img.renBuf, 0, int(dstX), int(dstY)); +} + +//------------------------------------------------------------------------ +void Agg2D::Image::premultiply() +{ + PixFormat pixf(renBuf); + pixf.premultiply(); +} + +//------------------------------------------------------------------------ +void Agg2D::Image::demultiply() +{ + PixFormat pixf(renBuf); + pixf.demultiply(); +} + diff --git a/agg2d/agg2d.h b/agg2d/agg2d.h new file mode 100644 index 0000000..9a0aa84 --- /dev/null +++ b/agg2d/agg2d.h @@ -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 Blender; + typedef agg::comp_op_adaptor_rgba BlenderComp; + typedef agg::blender_rgba_pre BlenderPre; + typedef agg::comp_op_adaptor_rgba_pre BlenderCompPre; + + typedef agg::pixfmt_alpha_blend_rgba PixFormat; + typedef agg::pixfmt_custom_blend_rgba PixFormatComp; + typedef agg::pixfmt_alpha_blend_rgba PixFormatPre; + typedef agg::pixfmt_custom_blend_rgba PixFormatCompPre; + + typedef agg::renderer_base RendererBase; + typedef agg::renderer_base RendererBaseComp; + typedef agg::renderer_base RendererBasePre; + typedef agg::renderer_base RendererBaseCompPre; + + typedef agg::renderer_scanline_aa_solid RendererSolid; + typedef agg::renderer_scanline_aa_solid RendererSolidComp; + + typedef agg::span_allocator SpanAllocator; + typedef agg::pod_auto_array GradientArray; + + typedef agg::span_gradient, agg::gradient_x, GradientArray> LinearGradientSpan; + typedef agg::span_gradient, 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 FontCacheManager; + typedef FontCacheManager::gray8_adaptor_type FontRasterizer; + typedef FontCacheManager::gray8_scanline_type FontScanline; + + typedef agg::conv_curve ConvCurve; + typedef agg::conv_stroke ConvStroke; + typedef agg::conv_transform PathTransform; + typedef agg::conv_transform 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 + + diff --git a/autogen.sh b/autogen.sh new file mode 100644 index 0000000..a476cff --- /dev/null +++ b/autogen.sh @@ -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 diff --git a/bin/AggConfig.cmake.in b/bin/AggConfig.cmake.in new file mode 100644 index 0000000..0a61f58 --- /dev/null +++ b/bin/AggConfig.cmake.in @@ -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 ) diff --git a/bin/AggConfigOutBuild.cmake.in b/bin/AggConfigOutBuild.cmake.in new file mode 100644 index 0000000..80a7ca1 --- /dev/null +++ b/bin/AggConfigOutBuild.cmake.in @@ -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 ) diff --git a/bin/FindAgg.cmake b/bin/FindAgg.cmake new file mode 100644 index 0000000..f17ad24 --- /dev/null +++ b/bin/FindAgg.cmake @@ -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) diff --git a/bin/FindEXPAT.cmake b/bin/FindEXPAT.cmake new file mode 100644 index 0000000..02558d5 --- /dev/null +++ b/bin/FindEXPAT.cmake @@ -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) diff --git a/bin/FindFreetype.cmake b/bin/FindFreetype.cmake new file mode 100644 index 0000000..19b4ffc --- /dev/null +++ b/bin/FindFreetype.cmake @@ -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 ). +# 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) diff --git a/bin/UseAgg.cmake.in b/bin/UseAgg.cmake.in new file mode 100644 index 0000000..db44cf6 --- /dev/null +++ b/bin/UseAgg.cmake.in @@ -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) + + diff --git a/cmake_install.html b/cmake_install.html new file mode 100644 index 0000000..85e0918 --- /dev/null +++ b/cmake_install.html @@ -0,0 +1,234 @@ + + + + + + + + +

Cmake to generate projects files or makefile.

+ +
+ +You start with downloading and installing Cmake  http:://www.cmake.org
+
+
+ + + +

On windows

+ +On windows call the program CmakeSetup.exe, distributed with +Cmake.
+ +This has a graphical interface used to generate your project files or +makefiles.
+ +
+ +Asumming Agg is installed at
C:\agg\agg-2.4
+ +
+ +
In CmakeSetup.exe choose:
+ +
+ +Where is the source code:
C:\agg\agg-2.4
+ +Where to build the binaries: C:\agg\agg-2.4_Build
+ +
+ +The options:
+
    +
  • +agg_USE_EXPAT
  • + +
  • +agg_USE_FREETYPE
  • +
      +
    • Get the library + headers from: http://gnuwin32.sourceforge.net/packages/freetype.htm
    • +
    • tested with the download called: "Complete package, except sources" 
    • +
    • This will add a key to your registry, which is searched for by Cmake, if not oke, use next step.
    • +
    • Do set FREETYPE_DIR in your environment to the location where you installed the above.
      +
    • +
    +
  • +agg_USE_GPC
  • +
      +
    • Internal files, but GPL, so an option.
    • +
    +
  • +agg_USE_SDL_PLATFORM
  • +
      +
    • Todo
    • +
    +
  • agg_USE_PACK
  • + +
+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.
+In case of problem, un-comment the MESSAGE statements in those script, to see what is going on. + +

On Unix alikes

+ +Asumming Agg is installed at /home/me/agg/agg-2.4
+ +
+ +
cd /home/me/agg
+ +mkdir agg_build
+ +cd /home/me/agg/agg_build
+
+Here you generate makefiles with a GUI with:
+
+ccmake ../agg-2.4
+
+OR using commandline for example:
+
+cmake  -Dagg_USE_FREETYPE:BOOL=ON -Dagg_USE_EXPAT:BOOL=ON ../agg-2.4
+
+ +The options:
+
    +
  • +agg_USE_EXPAT
  • +
      +
    • Requires expat to be installed.
    • +
    +
  • +agg_USE_FREETYPE
  • +
      +
    • Requires freetype-devel to be installed. (e.g. on Fedora:  yum install freetype-devel )
    • +
    +
  • +agg_USE_GPC
  • +
      +
    • Part of Agg for the moment, but GPL, that is why its optional.
    • +
    +
  • +agg_USE_SDL_PLATFORM
  • +
      +
    • SDL needs to be installed.
    • +
    +
  • agg_USE_PACK
  • + +
+After generating the makefiles, you just type:
+make +You can also build directly in the agg checkout dircetory, but that is bad habit.
+
+When all is compiled, you can execute the samples already from the examples directory in your build tree.
+Now you can login as root and install Agg as you compiled it.
+So you type:
+
+make install
+
+This installes your file in /usr/local.
+

My Own Application

+Nice but what if i want to detect Agg libraries and headers etc. for +use in  my own application. For that you find in the resulting +build directory created by Cmake,  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 source directory. Again +choose your build directory, and configure.
+This will result in project/make files for the demo application contained in my_demo.cpp.
+
+In principle this is needed ( see myapp/CMakeLists.txt ):
+
+FIND_PACKAGE( Agg )
+IF( AGG_FOUND )
+    INCLUDE_DIRECTORIES(${AGG_INCLUDE_DIRS})
+    LINK_LIBRARIES(${AGG_LIBRARIES})
+    INCLUDE(${AGG_USE_FILE})
+ELSE( AGG_FOUND )
+    MESSAGE( "AGG library was not found" )
+ENDIF( AGG_FOUND )
+
+If you look in your C:\agg\agg-2.4_Build you will see that AggConfig.cmake and UseAgg.cmake, they contain all the information you need to have to use Agg in your application. Study FindAgg.cmake to know who Agg install dir is found.
+Also be aware  that the file C:\agg\agg-2.4_Build\bin\AggConfigOutBuild.cmake is installed as AggConfig.cmake by make install are inside the packages.
+The file C:\agg\agg-2.4_Build\AggConfig.cmake is setup such that you can use it from with in the build directory itself, using the Agg header files from the source directory.
+This is the same as when building the agg libraries itself.
+Only when packaging and/or doing a make install, the headers will be really installed.
+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 antigrain-0.1.1-win32.exe to install on windows, a registry key  "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Agg\\antigrain 0.1.1]/bin" is generated, which is used by FindAgg.cmake to find the installation.
+
+On Unix you can, after installing Agg, go to /home/me/agg/agg_build/myapp and type this for an inside build:
+
+
cmake .
+

+or for an outside build:
+
+
mkdir ../buildmyapp
+cd
../buildmyapp
+cmake ../myapp
+

+If you do not want to install, you can set AGG_DIR first, to use the build without installing, like:
+
+export AGG_DIR=/home/me/agg/agg_build
+
+
+

Cpack to make distributions

+If enabled agg_USE_PACK, you get an extra target.
+On windows have gzip and nsis installed, they are used to generate the +setup/installer script and zip files, and found automatically:
+
+http://nsis.sourceforge.net
+http://www.7-zip.org
+
+Parts of the Cmake system  is Cpack. After a build of Agg, + you get an extra target to PACKAGE, but you can do it by hand +also.
+Calling the Cmake tool: cpack.exe -C debug or cpack.exe -C  release on the command line, will result in files like:
+
+antigrain-0.1.1-win32.exe      # this is the installers script for Agg on windows.
+antigrain-0.1.1-win32.zip       #contains the same, and can be installed by hand
+
+
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 FindAgg.cmake, if you use the zip file, you will need to set AGG_DIR in your environment to reach the same.
+
+On unix you type:
+
+cpack -C debug on the line, and this gives you files like:
+
+antigrain-0.1.1-Linux.sh
+antigrain-0.1.1-Linux.tar.gz
+antigrain-0.1.1-Linux.tar.Z
+antigrain-0.1.1-Linux.tar.bz2
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..4e1cb48 --- /dev/null +++ b/configure.ac @@ -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 +) + diff --git a/copying b/copying new file mode 100644 index 0000000..f176814 --- /dev/null +++ b/copying @@ -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. + diff --git a/distclean b/distclean new file mode 100644 index 0000000..1535b16 --- /dev/null +++ b/distclean @@ -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 {} \; + + diff --git a/doc/AggCP-Gradients1_readme.txt b/doc/AggCP-Gradients1_readme.txt new file mode 100644 index 0000000..6f93e66 --- /dev/null +++ b/doc/AggCP-Gradients1_readme.txt @@ -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 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 +================================================================================ diff --git a/examples/BeOS/Makefile b/examples/BeOS/Makefile new file mode 100644 index 0000000..5a6de15 --- /dev/null +++ b/examples/BeOS/Makefile @@ -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 + + diff --git a/examples/BeOS/readme.txt b/examples/BeOS/readme.txt new file mode 100644 index 0000000..e691517 --- /dev/null +++ b/examples/BeOS/readme.txt @@ -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 +... diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..8d46720 --- /dev/null +++ b/examples/CMakeLists.txt @@ -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 ) + + + + + + diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 0000000..5e18329 --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,248 @@ +EXTRA_DIST= X11/Makefile interactive_polygon.h pixel_formats.h win32_api/aa_demo/Makefile win32_api/aa_demo/aa_demo.dsp win32_api/aa_demo/aa_demo.dsw win32_api/Makefile win32_api/examples.dsw win32_api/aa_test/Makefile win32_api/aa_test/aa_test.dsp win32_api/aa_test/aa_test.dsw win32_api/alpha_gradient/Makefile win32_api/alpha_gradient/alpha_gradient.dsp win32_api/alpha_gradient/alpha_gradient.dsw win32_api/alpha_mask/Makefile win32_api/alpha_mask/alpha_mask.dsp win32_api/alpha_mask/alpha_mask.dsw win32_api/alpha_mask2/Makefile win32_api/alpha_mask2/alpha_mask2.dsp win32_api/alpha_mask2/alpha_mask2.dsw win32_api/alpha_mask3/Makefile win32_api/alpha_mask3/alpha_mask3.dsp win32_api/alpha_mask3/alpha_mask3.dsw win32_api/bezier_div/Makefile win32_api/bezier_div/bezier_div.dsp win32_api/bezier_div/bezier_div.dsw win32_api/bspline/Makefile win32_api/bspline/bspline.dsp win32_api/bspline/bspline.dsw win32_api/circles/Makefile win32_api/circles/circles.dsp win32_api/circles/circles.dsw win32_api/component_rendering/Makefile win32_api/component_rendering/component_rendering.dsp win32_api/component_rendering/component_rendering.dsw win32_api/compositing/Makefile win32_api/compositing/compositing.dsp win32_api/compositing/compositing.dsw win32_api/compositing/readme win32_api/conv_contour/Makefile win32_api/conv_contour/conv_contour.dsp win32_api/conv_contour/conv_contour.dsw win32_api/conv_dash_marker/Makefile win32_api/conv_dash_marker/conv_dash_marker.dsp win32_api/conv_dash_marker/conv_dash_marker.dsw win32_api/conv_stroke/Makefile win32_api/conv_stroke/conv_stroke.dsp win32_api/conv_stroke/conv_stroke.dsw win32_api/distortions/Makefile win32_api/distortions/distortions.dsp win32_api/distortions/distortions.dsw win32_api/distortions/readme win32_api/freetype_test/Makefile win32_api/freetype_test/freetype_test.dsp win32_api/freetype_test/freetype_test.dsw win32_api/freetype_test/readme win32_api/gamma_correction/Makefile win32_api/gamma_correction/gamma_correction.dsp win32_api/gamma_correction/gamma_correction.dsw win32_api/gamma_ctrl/Makefile win32_api/gamma_ctrl/gamma_ctrl.dsp win32_api/gamma_ctrl/gamma_ctrl.dsw win32_api/gouraud/Makefile win32_api/gouraud/gouraud.dsp win32_api/gouraud/gouraud.dsw win32_api/gpc_test/Makefile win32_api/gpc_test/gpc_test.dsp win32_api/gpc_test/gpc_test.dsw win32_api/gradients/Makefile win32_api/gradients/gradients.dsp win32_api/gradients/gradients.dsw win32_api/gradients/settings.dat win32_api/graph_test/Makefile win32_api/graph_test/graph_test.dsp win32_api/graph_test/graph_test.dsw win32_api/idea/Makefile win32_api/idea/idea.dsp win32_api/idea/idea.dsw win32_api/image1/Makefile win32_api/image1/image1.dsp win32_api/image1/image1.dsw win32_api/image1/readme win32_api/image_alpha/Makefile win32_api/image_alpha/image_alpha.dsp win32_api/image_alpha/image_alpha.dsw win32_api/image_alpha/readme win32_api/image_filters/Makefile win32_api/image_filters/image_filters.dsp win32_api/image_filters/image_filters.dsw win32_api/image_filters/readme win32_api/image_filters2/Makefile win32_api/image_filters2/image_filters2.dsp win32_api/image_filters2/image_filters2.dsw win32_api/image_filters2/readme win32_api/image_fltr_graph/Makefile win32_api/image_fltr_graph/image_fltr_graph.dsp win32_api/image_fltr_graph/image_fltr_graph.dsw win32_api/image_perspective/Makefile win32_api/image_perspective/image_perspective.dsp win32_api/image_perspective/image_perspective.dsw win32_api/image_perspective/readme win32_api/image_resample/Makefile win32_api/image_resample/image_resample.dsp win32_api/image_resample/image_resample.dsw win32_api/image_resample/readme win32_api/image_transforms/Makefile win32_api/image_transforms/image_transforms.dsp win32_api/image_transforms/image_transforms.dsw win32_api/image_transforms/readme! win32_api/line_patterns/Makefile win32_api/line_patterns/line_patterns.dsp win32_api/line_patterns/line_patterns.dsw win32_api/lion/Makefile win32_api/lion/lion.dsp win32_api/lion/lion.dsw win32_api/lion_lens/Makefile win32_api/lion_lens/lion_lens.dsp win32_api/lion_lens/lion_lens.dsw win32_api/lion_outline/Makefile win32_api/lion_outline/lion_outline.dsp win32_api/lion_outline/lion_outline.dsw win32_api/mol_view/Makefile win32_api/mol_view/mol_view.dsp win32_api/mol_view/mol_view.dsw win32_api/mol_view/readme win32_api/multi_clip/Makefile win32_api/multi_clip/multi_clip.dsp win32_api/multi_clip/multi_clip.dsw win32_api/pattern_fill/Makefile win32_api/pattern_fill/pattern_fill.dsp win32_api/pattern_fill/pattern_fill.dsw win32_api/pattern_perspective/pattern_perspective.dsp win32_api/pattern_perspective/pattern_perspective.dsw win32_api/pattern_resample/Makefile win32_api/pattern_resample/pattern_resample.dsp win32_api/pattern_resample/pattern_resample.dsw win32_api/perspective/Makefile win32_api/perspective/perspective.dsp win32_api/perspective/perspective.dsw win32_api/polymorphic_renderer/Makefile win32_api/polymorphic_renderer/polymorphic_renderer.dsp win32_api/polymorphic_renderer/polymorphic_renderer.dsw win32_api/pure_api/StdAfx.cpp win32_api/pure_api/StdAfx.h win32_api/pure_api/pure_api.cpp win32_api/pure_api/pure_api.dsp win32_api/pure_api/pure_api.dsw win32_api/pure_api/pure_api.h win32_api/pure_api/pure_api.ico win32_api/pure_api/pure_api.rc win32_api/pure_api/resource.h win32_api/pure_api/small.ico win32_api/raster_text/Makefile win32_api/raster_text/raster_text.dsp win32_api/raster_text/raster_text.dsw win32_api/rasterizers/Makefile win32_api/rasterizers/rasterizers.dsp win32_api/rasterizers/rasterizers.dsw win32_api/rasterizers2/Makefile win32_api/rasterizers2/rasterizers2.dsp win32_api/rasterizers2/rasterizers2.dsw win32_api/rounded_rect/Makefile win32_api/rounded_rect/rounded_rect.dsp win32_api/rounded_rect/rounded_rect.dsw win32_api/scanline_boolean/Makefile win32_api/scanline_boolean/scanline_boolean.dsp win32_api/scanline_boolean/scanline_boolean.dsw win32_api/scanline_boolean2/Makefile win32_api/scanline_boolean2/scanline_boolean2.dsp win32_api/scanline_boolean2/scanline_boolean2.dsw win32_api/simple_blur/Makefile win32_api/simple_blur/simple_blur.dsp win32_api/simple_blur/simple_blur.dsw win32_api/trans_curve1/Makefile win32_api/trans_curve1/trans_curve1.dsp win32_api/trans_curve1/trans_curve1.dsw win32_api/trans_curve2/Makefile win32_api/trans_curve2/trans_curve2.dsp win32_api/trans_curve2/trans_curve2.dsw win32_api/trans_polar/Makefile win32_api/trans_polar/trans_polar.dsp win32_api/trans_polar/trans_polar.dsw win32_api/truetype_test/Makefile win32_api/truetype_test/truetype_test.dsp win32_api/truetype_test/truetype_test.dsw + +if ENABLE_EXAMPLES + +if ENABLE_WIN32_TT +W32TTP=truetype_test trans_curve1 trans_curve2 +endif + +if ENABLE_FT +FTP=freetype_test trans_curve2_ft trans_curve1_ft +endif + +if ENABLE_GPC +GPCP=gpc_test +endif + +INCLUDES=-I$(top_srcdir)/include -I$(top_srcdir)/font_freetype/ -I$(top_srcdir)/gpc -I$(top_srcdir)/font_win32_tt + +noinst_LTLIBRARIES=libexamples.la +libexamples_la_SOURCES=parse_lion.cpp make_gb_poly.cpp make_arrows.cpp interactive_polygon.cpp + +noinst_PROGRAMS=aa_demo aa_test alpha_gradient alpha_mask2 alpha_mask3 alpha_mask bezier_div bspline circles component_rendering compositing conv_contour conv_dash_marker conv_stroke distortions gamma_correction gamma_ctrl gouraud gradients graph_test idea image1 image_alpha image_filters2 image_filters image_fltr_graph image_perspective image_resample image_transforms line_patterns lion lion_lens lion_outline mol_view multi_clip pattern_fill pattern_perspective pattern_resample perspective polymorphic_renderer rasterizers2 rasterizers raster_text rounded_rect scanline_boolean2 scanline_boolean simple_blur trans_polar $(GPCP) $(W32TTP) $(FTP) + + +aa_demo_SOURCES=aa_demo.cpp +aa_demo_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +aa_test_SOURCES=aa_test.cpp +aa_test_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +alpha_gradient_SOURCES=alpha_gradient.cpp +alpha_gradient_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +alpha_mask2_SOURCES=alpha_mask2.cpp +alpha_mask2_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +alpha_mask3_SOURCES=alpha_mask3.cpp +alpha_mask3_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +alpha_mask_SOURCES=alpha_mask.cpp +alpha_mask_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +bezier_div_SOURCES=bezier_div.cpp +bezier_div_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +bspline_SOURCES=bspline.cpp +bspline_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +circles_SOURCES=circles.cpp +circles_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +component_rendering_SOURCES=component_rendering.cpp +component_rendering_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +compositing_SOURCES=compositing.cpp +compositing_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +conv_contour_SOURCES=conv_contour.cpp +conv_contour_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +conv_dash_marker_SOURCES=conv_dash_marker.cpp +conv_dash_marker_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +conv_stroke_SOURCES=conv_stroke.cpp +conv_stroke_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +distortions_SOURCES=distortions.cpp +distortions_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +gamma_correction_SOURCES=gamma_correction.cpp +gamma_correction_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +gamma_ctrl_SOURCES=gamma_ctrl.cpp +gamma_ctrl_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +gouraud_SOURCES=gouraud.cpp +gouraud_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +gradients_SOURCES=gradients.cpp +gradients_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +graph_test_SOURCES=graph_test.cpp +graph_test_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +idea_SOURCES=idea.cpp +idea_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +image1_SOURCES=image1.cpp +image1_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +image_alpha_SOURCES=image_alpha.cpp +image_alpha_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +image_filters2_SOURCES=image_filters2.cpp +image_filters2_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +image_filters_SOURCES=image_filters.cpp +image_filters_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +image_fltr_graph_SOURCES=image_fltr_graph.cpp +image_fltr_graph_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +image_perspective_SOURCES=image_perspective.cpp +image_perspective_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +image_resample_SOURCES=image_resample.cpp +image_resample_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +image_transforms_SOURCES=image_transforms.cpp +image_transforms_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +line_patterns_SOURCES=line_patterns.cpp +line_patterns_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +lion_SOURCES=lion.cpp +lion_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +lion_lens_SOURCES=lion_lens.cpp +lion_lens_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +lion_outline_SOURCES=lion_outline.cpp +lion_outline_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +mol_view_SOURCES=mol_view.cpp +mol_view_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +multi_clip_SOURCES=multi_clip.cpp +multi_clip_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +pattern_fill_SOURCES=pattern_fill.cpp +pattern_fill_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +pattern_perspective_SOURCES=pattern_perspective.cpp +pattern_perspective_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +pattern_resample_SOURCES=pattern_resample.cpp +pattern_resample_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +perspective_SOURCES=perspective.cpp +perspective_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +polymorphic_renderer_SOURCES=polymorphic_renderer.cpp +polymorphic_renderer_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +rasterizers2_SOURCES=rasterizers2.cpp +rasterizers2_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +rasterizers_SOURCES=rasterizers.cpp +rasterizers_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +raster_text_SOURCES=raster_text.cpp +raster_text_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +rounded_rect_SOURCES=rounded_rect.cpp +rounded_rect_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +scanline_boolean2_SOURCES=scanline_boolean2.cpp +scanline_boolean2_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +scanline_boolean_SOURCES=scanline_boolean.cpp +scanline_boolean_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +simple_blur_SOURCES=simple_blur.cpp +simple_blur_LDFLAGS= libexamples.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +trans_polar_SOURCES=trans_polar.cpp +trans_polar_LDFLAGS= $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +freetype_test_SOURCES=freetype_test.cpp +freetype_test_CXXFLAGS=@FREETYPE_CFLAGS@ +freetype_test_LDFLAGS= $(top_builddir)/font_freetype/libaggfontfreetype.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +trans_curve2_ft_SOURCES=trans_curve2_ft.cpp interactive_polygon.cpp +trans_curve2_ft_CXXFLAGS=@FREETYPE_CFLAGS@ +trans_curve2_ft_LDFLAGS= $(top_builddir)/font_freetype/libaggfontfreetype.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +trans_curve1_ft_SOURCES=trans_curve1_ft.cpp interactive_polygon.cpp +trans_curve1_ft_CXXFLAGS=@FREETYPE_CFLAGS@ +trans_curve1_ft_LDFLAGS= $(top_builddir)/font_freetype/libaggfontfreetype.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +gpc_test_SOURCES=gpc_test.cpp +gpc_test_LDFLAGS= libexamples.la $(top_builddir)/gpc/libagggpc.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +truetype_test_SOURCES=truetype_test.cpp +truetype_test_LDFLAGS= $(top_builddir)/font_win32_tt/libaggfontwin32tt.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +trans_curve1_SOURCES=trans_curve1.cpp +trans_curve1_LDFLAGS= libexamples.la $(top_builddir)/font_win32_tt/libaggfontwin32tt.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +trans_curve2_SOURCES=trans_curve2.cpp +trans_curve2_LDFLAGS= libexamples.la $(top_builddir)/font_win32_tt/libaggfontwin32tt.la $(top_builddir)/src/platform/@PREFERED_PLATFORM@/libaggplatform@PREFERED_PLATFORM@.la $(top_builddir)/src/libagg.la + + +endif diff --git a/examples/X11/Makefile b/examples/X11/Makefile new file mode 100644 index 0000000..a27e9fb --- /dev/null +++ b/examples/X11/Makefile @@ -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 + + diff --git a/examples/X11/readme.txt b/examples/X11/readme.txt new file mode 100644 index 0000000..74034c9 --- /dev/null +++ b/examples/X11/readme.txt @@ -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 +... \ No newline at end of file diff --git a/examples/aa_demo.cpp b/examples/aa_demo.cpp new file mode 100644 index 0000000..d46a895 --- /dev/null +++ b/examples/aa_demo.cpp @@ -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 + 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_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 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 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 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_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 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; +} + + diff --git a/examples/aa_test.cpp b/examples/aa_test.cpp new file mode 100644 index 0000000..577a136 --- /dev/null +++ b/examples/aa_test.cpp @@ -0,0 +1,581 @@ +#include +#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 renderer_base_type; +typedef agg::renderer_scanline_aa_solid renderer_scanline_type; +typedef agg::scanline_u8 scanline_type; +typedef agg::rasterizer_scanline_aa<> rasterizer_type; + +template 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 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 m_dash; + agg::conv_stroke m_stroke; + agg::conv_stroke > 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 +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 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 span_allocator_type; + typedef agg::pod_auto_array color_array_type; + typedef agg::span_gradient span_gradient_type; + + typedef agg::renderer_scanline_aa 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 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 span_allocator_type; + typedef agg::pod_auto_array color_array_type; + typedef agg::span_gradient span_gradient_type; + typedef agg::renderer_scanline_aa 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 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 gouraud_span_gen_type; + typedef agg::renderer_scanline_aa 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; +} + + diff --git a/examples/agg2d_demo.cpp b/examples/agg2d_demo.cpp new file mode 100644 index 0000000..2e94269 --- /dev/null +++ b/examples/agg2d_demo.cpp @@ -0,0 +1,419 @@ +#include +#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; +} + + + + + + diff --git a/examples/alpha_gradient.cpp b/examples/alpha_gradient.cpp new file mode 100644 index 0000000..6bb5314 --- /dev/null +++ b/examples/alpha_gradient.cpp @@ -0,0 +1,373 @@ +#include +#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 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 + 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 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 span_allocator_type; + + + // Gradient colors array adaptor + //----------------- + typedef agg::pod_auto_array gradient_colors_type; + + + // Finally, the gradient span generator working with the color_type + // color type. + //----------------- + typedef agg::span_gradient span_gradient_type; + + + // Gradient alpha array adaptor + //----------------- + typedef agg::pod_auto_array gradient_alpha_type; + + // The alpha gradient span converter working with the color_type + // color type. + //----------------- + typedef agg::span_gradient_alpha span_gradient_alpha_type; + + + // Span converter type + //----------------- + typedef agg::span_converter 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; +} + + diff --git a/examples/alpha_mask.cpp b/examples/alpha_mask.cpp new file mode 100644 index 0000000..e2bd777 --- /dev/null +++ b/examples/alpha_mask.cpp @@ -0,0 +1,203 @@ +#include +#include +#include +#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 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 ren_base; + typedef agg::renderer_scanline_aa_solid 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 scanline_type; + typedef agg::renderer_base ren_base; + typedef agg::renderer_scanline_aa_solid 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 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; +} + + + + + + diff --git a/examples/alpha_mask2.cpp b/examples/alpha_mask2.cpp new file mode 100644 index 0000000..a278f24 --- /dev/null +++ b/examples/alpha_mask2.cpp @@ -0,0 +1,419 @@ +#include +#include +#include +#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 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 + { + 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 + { + 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 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 ren_base; + typedef agg::renderer_scanline_aa_solid 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_amask_type; + typedef agg::renderer_base amask_ren_type; + typedef agg::renderer_base 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 rs(r); + agg::renderer_scanline_aa_solid 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 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 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 renderer_type; + renderer_type ren(r, profile); + + typedef agg::rasterizer_outline_aa 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 grad_color; + typedef agg::gradient_circle grad_func; + typedef agg::span_interpolator_linear<> interpolator_type; + typedef agg::span_gradient 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 sa; + interpolator_type inter(grm); + span_grad_type sg(inter, grf, grc, 0, 10); + agg::renderer_scanline_aa, + 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; +} + + + + + + diff --git a/examples/alpha_mask3.cpp b/examples/alpha_mask3.cpp new file mode 100644 index 0000000..095056e --- /dev/null +++ b/examples/alpha_mask3.cpp @@ -0,0 +1,569 @@ +#include +#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 m_polygons; + agg::rbox_ctrl 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 rb(pf); + agg::renderer_scanline_aa_solid > ren(rb); + + agg::gsv_text txt; + agg::conv_stroke 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 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 ren_base; + typedef agg::renderer_scanline_aa_solid 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 + void perform_rendering(VertexSource& vs) + { + pixfmt_type pixf(rbuf_window()); + + typedef agg::pixfmt_amask_adaptor pixfmt_amask_type; + typedef agg::renderer_base amask_ren_type; + + + pixfmt_amask_type pixfa(pixf, m_alpha_mask); + amask_ren_type rbase(pixfa); + agg::renderer_scanline_aa_solid 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 rb(pf); + agg::renderer_scanline_aa_solid > 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 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 trans_gb_poly(gb_poly, mtx1); + agg::conv_transform 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 > 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 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 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 > 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 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 trans(glyph, mtx); + agg::conv_curve > 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 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; +} + + diff --git a/examples/art/1.sdf b/examples/art/1.sdf new file mode 100644 index 0000000..936d738 --- /dev/null +++ b/examples/art/1.sdf @@ -0,0 +1,2825 @@ +MFCD00133935 + Mt7.00 09020221412D + + 89 94 0 0 1 0 0 0 0 0999 V2000 + 18.0501 7.6722 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.4329 8.4590 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.4429 8.3180 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 15.8258 9.1048 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.8358 8.9638 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.2186 9.7506 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.5915 10.6785 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.5815 10.8195 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.1986 10.0327 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6636 11.0513 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.5225 12.0413 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 14.3094 12.6585 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 15.2373 12.2856 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.3783 11.2956 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 16.0241 12.9028 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.9520 12.5299 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.0720 11.6117 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.1525 11.9139 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.1490 13.0590 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.8965 13.9428 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.8970 13.5264 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.8970 12.4319 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.1636 11.5128 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.8889 12.1827 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.9520 13.5480 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.5947 12.4142 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.4536 13.4042 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 11.8078 11.7970 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 10.8799 12.1699 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 10.7389 13.1599 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5257 13.7770 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.5157 13.9181 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.8886 14.8460 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.2714 15.6328 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.2814 15.4918 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.9086 14.5639 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.0931 11.5527 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.2341 10.5627 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1652 11.9256 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 8.3783 11.3084 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 7.4505 11.6813 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3094 12.6713 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 6.6636 11.0641 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 5.7357 11.4370 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 5.5947 12.4270 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.6668 12.7998 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.5257 13.7898 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.8799 12.1827 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.9489 10.8198 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.0899 9.8298 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.0210 11.1927 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.2341 10.5755 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 3.3752 9.5855 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.3031 9.2127 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.3062 10.9484 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.1652 11.9384 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1.5194 10.3312 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 0.5576 10.6050 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0000 9.7749 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.6172 8.9881 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.5562 9.3319 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 2.3863 8.7743 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.2843 9.2144 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 2.3184 7.7766 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.1485 7.2190 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 4.0465 7.6590 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.8766 7.1014 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.7745 7.5415 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.6046 6.9839 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 7.5026 7.4239 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.5705 8.4216 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 8.3327 6.8663 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.0806 6.2213 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.1827 5.7812 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 3.9107 5.6636 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.8429 4.6660 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 4.6730 4.1083 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.6051 3.1106 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.4352 2.5530 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.3673 1.5553 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 6.1974 0.9977 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.0954 1.4378 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 6.1296 0.0000 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 2.9449 4.2259 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.1148 4.7835 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 2.8770 3.2282 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 8.5194 10.3184 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.7325 9.7013 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.4473 9.9456 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 3 4 1 0 0 0 0 + 4 5 2 0 1 0 0 + 5 6 1 0 0 0 0 + 6 7 2 0 2 0 0 + 7 8 1 0 0 0 0 + 8 9 2 0 2 0 0 + 9 4 1 0 0 0 0 + 7 10 1 0 0 0 0 + 10 11 1 0 0 0 0 + 11 12 1 0 0 0 0 + 12 13 1 0 0 0 0 + 13 14 2 0 0 0 0 + 13 15 1 0 0 0 0 + 15 16 1 0 0 0 0 + 16 17 1 0 0 0 0 + 17 18 1 0 0 0 0 + 18 19 1 0 0 0 0 + 19 20 1 0 0 0 0 + 20 21 1 0 0 0 0 + 21 22 1 0 0 0 0 + 22 23 1 0 0 0 0 + 23 18 1 0 0 0 0 + 22 24 1 0 0 0 0 + 24 16 1 0 0 0 0 + 20 25 1 0 0 0 0 + 25 16 1 0 0 0 0 + 11 26 1 6 0 0 0 + 26 27 2 0 0 0 0 + 26 28 1 0 0 0 0 + 28 29 1 0 0 0 0 + 29 30 1 0 0 0 0 + 30 31 1 0 0 0 0 + 31 32 2 0 2 0 0 + 32 33 1 0 0 0 0 + 33 34 2 0 2 0 0 + 34 35 1 0 0 0 0 + 35 36 2 0 2 0 0 + 36 31 1 0 0 0 0 + 29 37 1 6 0 0 0 + 37 38 2 0 0 0 0 + 37 39 1 0 0 0 0 + 39 40 1 0 0 0 0 + 40 41 1 0 0 0 0 + 41 42 2 0 0 0 0 + 41 43 1 0 0 0 0 + 43 44 1 0 0 0 0 + 44 45 1 0 0 0 0 + 45 46 1 0 0 0 0 + 46 47 1 0 0 0 0 + 46 48 2 0 0 0 0 + 44 49 1 6 0 0 0 + 49 50 2 0 0 0 0 + 49 51 1 0 0 0 0 + 51 52 1 0 0 0 0 + 52 53 1 0 0 0 0 + 53 54 1 0 0 0 0 + 52 55 1 1 0 0 0 + 55 56 2 0 0 0 0 + 55 57 1 0 0 0 0 + 57 58 1 0 0 0 0 + 58 59 1 0 0 0 0 + 59 60 1 0 0 0 0 + 60 61 1 0 0 0 0 + 61 57 1 0 0 0 0 + 61 62 1 6 0 0 0 + 62 63 2 0 0 0 0 + 62 64 1 0 0 0 0 + 64 65 1 0 0 0 0 + 65 66 1 0 0 0 0 + 66 67 1 0 0 0 0 + 67 68 1 0 0 0 0 + 68 69 1 0 0 0 0 + 69 70 1 0 0 0 0 + 70 71 2 0 0 0 0 + 70 72 1 0 0 0 0 + 65 73 1 1 0 0 0 + 73 74 2 0 0 0 0 + 73 75 1 0 0 0 0 + 75 76 1 0 0 0 0 + 76 77 1 0 0 0 0 + 77 78 1 0 0 0 0 + 78 79 1 0 0 0 0 + 79 80 1 0 0 0 0 + 80 81 1 0 0 0 0 + 81 82 2 0 0 0 0 + 81 83 1 0 0 0 0 + 76 84 1 1 0 0 0 + 84 85 1 0 0 0 0 + 84 86 2 0 0 0 0 + 40 87 1 1 0 0 0 + 87 88 1 0 0 0 0 + 87 89 1 0 0 0 0 +M END + +$$$$ +MFCD01318179 + Mt7.00 09020221422D + + 65 64 0 0 0 0 0 0 0 0999 V2000 + 1.9282 0.0000 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 2.4282 0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.2942 0.3660 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 1.5622 1.3660 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 2.9282 1.7321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.0622 2.2321 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 3.7942 1.2321 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 3.4282 2.5981 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.5622 3.0981 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 4.2942 2.0981 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 3.9282 3.4641 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.0622 3.9641 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 4.7942 2.9641 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 4.4282 4.3301 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.2942 3.8301 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 3.5622 4.8301 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 4.9282 5.1962 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.0622 5.6962 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 5.7942 4.6962 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 5.4282 6.0622 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.4282 6.0622 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.9282 6.9282 0.0000 Sn 0 0 0 0 0 0 0 0 0 0 0 0 + 7.7942 6.4282 0.0000 Br 0 0 0 0 0 0 0 0 0 0 0 0 + 7.4282 7.7942 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.4282 7.7942 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.9282 8.6603 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.0622 9.1603 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 9.7942 8.1603 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 9.4282 9.5263 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.5622 10.0263 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 10.2942 9.0263 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 9.9282 10.3923 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.7942 9.8923 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 9.0622 10.8923 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 10.4282 11.2583 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.5622 11.7583 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 11.2942 10.7583 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 10.9282 12.1244 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.7942 11.6244 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 10.0622 12.6244 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 11.4282 12.9904 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.9282 13.8564 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 10.5622 13.4904 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 12.2942 12.4904 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 6.0622 7.4282 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.0622 8.4282 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.1962 8.9282 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.6962 8.0622 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 5.6962 9.7942 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 4.3301 9.4282 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.8301 8.5622 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 4.8301 10.2942 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 3.4641 9.9282 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.9641 10.7942 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 2.9641 9.0622 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 2.5981 10.4282 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.0981 11.2942 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 2.0981 9.5622 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 1.7321 10.9282 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.2321 11.7942 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 1.2321 10.0622 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 0.8660 11.4282 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0000 11.9282 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 1.3660 12.2942 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 0.3660 10.5622 0.0000 F 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 2 4 1 0 0 0 0 + 2 5 1 0 0 0 0 + 5 6 1 0 0 0 0 + 5 7 1 0 0 0 0 + 5 8 1 0 0 0 0 + 8 9 1 0 0 0 0 + 8 10 1 0 0 0 0 + 8 11 1 0 0 0 0 + 11 12 1 0 0 0 0 + 11 13 1 0 0 0 0 + 11 14 1 0 0 0 0 + 14 15 1 0 0 0 0 + 14 16 1 0 0 0 0 + 14 17 1 0 0 0 0 + 17 18 1 0 0 0 0 + 17 19 1 0 0 0 0 + 17 20 1 0 0 0 0 + 20 21 1 0 0 0 0 + 21 22 1 0 0 0 0 + 22 23 1 0 0 0 0 + 22 24 1 0 0 0 0 + 24 25 1 0 0 0 0 + 25 26 1 0 0 0 0 + 26 27 1 0 0 0 0 + 26 28 1 0 0 0 0 + 26 29 1 0 0 0 0 + 29 30 1 0 0 0 0 + 29 31 1 0 0 0 0 + 29 32 1 0 0 0 0 + 32 33 1 0 0 0 0 + 32 34 1 0 0 0 0 + 32 35 1 0 0 0 0 + 35 36 1 0 0 0 0 + 35 37 1 0 0 0 0 + 35 38 1 0 0 0 0 + 38 39 1 0 0 0 0 + 38 40 1 0 0 0 0 + 38 41 1 0 0 0 0 + 41 42 1 0 0 0 0 + 41 43 1 0 0 0 0 + 41 44 1 0 0 0 0 + 22 45 1 0 0 0 0 + 45 46 1 0 0 0 0 + 46 47 1 0 0 0 0 + 47 48 1 0 0 0 0 + 47 49 1 0 0 0 0 + 47 50 1 0 0 0 0 + 50 51 1 0 0 0 0 + 50 52 1 0 0 0 0 + 50 53 1 0 0 0 0 + 53 54 1 0 0 0 0 + 53 55 1 0 0 0 0 + 53 56 1 0 0 0 0 + 56 57 1 0 0 0 0 + 56 58 1 0 0 0 0 + 56 59 1 0 0 0 0 + 59 60 1 0 0 0 0 + 59 61 1 0 0 0 0 + 59 62 1 0 0 0 0 + 62 63 1 0 0 0 0 + 62 64 1 0 0 0 0 + 62 65 1 0 0 0 0 +M END +> +MFCD01318179 + +$$$$ +MFCD00133860 + Mt7.00 09020221432D + +236240 0 0 1 0 0 0 0 0999 V2000 + 13.0062 10.2970 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.5062 9.4309 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.5062 9.4309 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.0062 8.5649 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.5062 7.6989 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 8.8399 2.3831 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 + 13.0062 6.8329 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.0062 6.8329 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5062 7.6989 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5062 5.9668 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 10.5062 5.9668 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 10.0062 5.1008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.5062 4.2348 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 9.0062 5.1008 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 8.8700 6.0915 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.4716 7.0087 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 7.8405 7.7844 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 7.0236 8.3611 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.0813 8.6960 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 6.2847 9.6751 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 5.0836 8.7642 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.0154 9.7619 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.1045 8.5608 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.2167 8.1007 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 2.6400 8.9177 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.4858 7.4182 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.7101 8.0492 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1.9662 6.5637 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 1.6964 5.6008 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 0.7057 5.7370 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.3283 6.6630 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1.6964 4.6008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.7057 4.4646 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1.9662 3.6379 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 2.4858 2.7835 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 1.7101 2.1524 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.7757 2.5086 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0000 1.8775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.6170 3.4960 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.2167 2.1009 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.6400 1.2840 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.1045 1.6409 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 5.0836 1.4374 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 5.0154 0.4397 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.1173 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 6.0813 1.5056 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.2847 0.5266 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 7.0236 1.8405 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 7.8405 2.4172 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 8.4716 3.1929 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.3260 2.6733 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 8.8700 4.1101 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 7.8064 1.4178 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 6.9238 0.9476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.6548 0.8885 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.0062 5.1008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5062 4.2348 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.0062 5.1008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.5062 7.6989 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.0062 6.8329 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 15.0062 8.5649 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 16.0062 8.5649 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.5062 9.4309 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.0062 10.2970 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 17.5062 9.4309 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 18.0062 10.2970 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 17.5062 11.1630 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.0062 12.0290 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.5062 12.8950 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.0062 13.7611 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.5062 14.6271 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 19.0062 10.2970 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.5062 9.4309 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 19.5062 11.1630 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 20.5062 11.1630 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 21.0062 10.2970 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.0062 10.2970 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.5062 9.4309 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.5062 11.1630 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.0062 12.0290 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.5062 12.8950 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 22.0062 12.0290 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 22.5062 12.8950 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 22.0062 13.7611 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.5062 14.6271 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 23.5062 12.8950 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.0062 12.0290 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 24.0062 13.7611 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 25.0062 13.7611 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 25.5062 12.8950 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.0062 12.0290 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.5062 11.1630 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.0062 10.2970 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 26.5062 11.1630 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 25.5062 14.6271 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.0062 15.4931 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 26.5062 14.6271 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 27.0062 15.4931 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 26.5062 16.3591 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.0062 17.2252 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.5062 18.0912 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.5062 18.0912 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 27.0062 18.9572 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 28.0062 15.4931 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5062 14.6271 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5062 16.3591 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 29.5062 16.3591 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 30.0062 15.4931 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0062 15.4931 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 14.6271 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 16.3591 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.0062 17.2252 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.5062 18.0912 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0062 17.2252 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 18.0912 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 32.5062 18.0912 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 33.0062 18.9572 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.0007 19.0617 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.2086 20.0399 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 33.3426 20.5399 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.5994 19.8708 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0062 18.9572 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.0062 18.9572 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 19.8232 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0062 20.6893 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 30.0062 20.6893 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.5062 21.5553 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5062 21.5553 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.0062 22.4213 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.0062 22.4213 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 21.5553 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.5062 21.5553 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0062 22.4213 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 23.2873 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 32.5062 23.2873 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 33.0062 24.1534 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.0062 24.1534 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.5062 25.0194 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0062 24.1534 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.0062 24.1534 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 25.0194 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0062 25.8854 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 30.0062 25.8854 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.5062 26.7515 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5062 26.7515 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.0062 27.6175 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 28.0062 25.8854 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 26.7514 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.5062 26.7514 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0062 27.6175 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 28.4835 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 31.0062 29.3495 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.0062 29.3495 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 30.2156 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0062 31.0816 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 30.0062 31.0816 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.5062 31.9476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5062 31.9476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.0062 32.8136 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5062 33.6797 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.0062 34.5457 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 29.5062 33.6797 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.0062 32.8136 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 31.9476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.5062 31.9476 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0062 32.8136 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 30.1972 33.4014 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.5062 34.3525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5062 34.3525 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.8152 33.4014 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 32.7663 33.0924 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.9742 32.1142 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 33.5094 33.7615 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 34.4605 33.4525 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 34.6684 32.4744 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.6194 32.1653 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.8273 31.1872 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 36.7784 30.8782 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 36.9863 29.9000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 36.2432 29.2309 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 37.9374 29.5910 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 35.2036 34.1216 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.9957 35.0998 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 36.1547 33.8126 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 36.8978 34.4818 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 37.8489 34.1727 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 38.0568 33.1946 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 38.5920 34.8419 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 39.5431 34.5328 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 39.7510 33.5547 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 40.7020 33.2457 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 41.4452 33.9148 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 40.9099 32.2675 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 40.2862 35.2020 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 40.0783 36.1801 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 41.2373 34.8930 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 41.9804 35.5621 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 42.9315 35.2531 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 43.1394 34.2749 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 43.6746 35.9222 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 44.6257 35.6132 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 45.3688 36.2823 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 45.1609 37.2605 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 46.3199 35.9733 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 47.0630 36.6424 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 46.8551 37.6206 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 48.0141 36.3334 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 48.2220 35.3553 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 48.7572 37.0025 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 49.7083 36.6935 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 50.4514 37.3627 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 50.2435 38.3408 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 51.4025 37.0536 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 52.1456 37.7228 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 53.0967 37.4138 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 53.3046 36.4356 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 53.8398 38.0829 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 53.7353 39.0774 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 54.6488 39.4842 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 55.3180 38.7410 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 54.8180 37.8750 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 55.2247 36.9614 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 56.2192 36.8569 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 54.6369 36.1524 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 51.9377 38.7009 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 50.9866 39.0099 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 52.6808 39.3701 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 41.7725 36.5402 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 40.8214 36.8493 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 42.5156 37.2094 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 36.6899 35.4599 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 35.7388 35.7689 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 37.4330 36.1290 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 32.5062 28.4835 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 33.0062 27.6175 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 33.0062 29.3495 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 2 4 1 0 0 0 0 + 4 5 1 0 0 0 0 + 5 7 1 0 0 0 0 + 7 8 1 0 0 0 0 + 8 9 2 0 0 0 0 + 8 10 1 0 0 0 0 + 10 11 1 0 0 0 0 + 11 12 1 0 0 0 0 + 12 13 2 0 0 0 0 + 14 12 1 1 0 0 0 + 14 15 1 0 0 0 0 + 15 16 1 0 0 0 0 + 16 17 1 0 0 0 0 + 17 18 1 0 0 0 0 + 18 19 1 0 0 0 0 + 19 20 1 1 0 0 0 + 19 21 1 0 0 0 0 + 21 22 2 0 0 0 0 + 21 23 1 0 0 0 0 + 23 24 1 0 0 0 0 + 24 25 1 6 0 0 0 + 24 26 1 0 0 0 0 + 26 27 2 0 0 0 0 + 26 28 1 0 0 0 0 + 28 29 1 0 0 0 0 + 29 30 1 6 0 0 0 + 30 31 1 0 0 0 0 + 29 32 1 0 0 0 0 + 32 33 2 0 0 0 0 + 32 34 1 0 0 0 0 + 34 35 1 0 0 0 0 + 35 36 1 6 0 0 0 + 36 37 1 0 0 0 0 + 37 38 1 0 0 0 0 + 37 39 1 0 0 0 0 + 35 40 1 0 0 0 0 + 40 41 2 0 0 0 0 + 40 42 1 0 0 0 0 + 42 43 1 0 0 0 0 + 43 44 1 6 0 0 0 + 44 45 1 0 0 0 0 + 43 46 1 0 0 0 0 + 46 47 2 0 0 0 0 + 46 48 1 0 0 0 0 + 48 49 1 0 0 0 0 + 49 50 1 0 0 0 0 + 50 51 2 0 0 0 0 + 50 52 1 0 0 0 0 + 52 14 1 0 0 0 0 + 49 53 1 0 0 0 0 + 53 54 1 0 0 0 0 + 53 55 1 6 0 0 0 + 10 56 1 6 0 0 0 + 56 57 1 0 0 0 0 + 56 58 1 0 0 0 0 + 5 59 1 1 0 0 0 + 59 60 2 0 0 0 0 + 59 61 1 0 0 0 0 + 61 62 1 0 0 0 0 + 62 63 1 0 0 0 0 + 63 64 2 0 0 0 0 + 63 65 1 0 0 0 0 + 65 66 1 0 0 0 0 + 66 67 1 0 0 0 0 + 67 68 1 0 0 0 0 + 68 69 1 0 0 0 0 + 69 70 1 0 0 0 0 + 70 71 1 0 0 0 0 + 66 72 1 1 0 0 0 + 72 73 2 0 0 0 0 + 72 74 1 0 0 0 0 + 74 75 1 0 0 0 0 + 75 76 1 0 0 0 0 + 76 77 1 0 0 0 0 + 77 78 1 0 0 0 0 + 77 79 1 0 0 0 0 + 75 80 1 6 0 0 0 + 80 81 2 0 0 0 0 + 80 82 1 0 0 0 0 + 82 83 1 0 0 0 0 + 83 84 1 0 0 0 0 + 84 85 1 0 0 0 0 + 83 86 1 1 0 0 0 + 86 87 2 0 0 0 0 + 86 88 1 0 0 0 0 + 88 89 1 0 0 0 0 + 89 90 1 0 0 0 0 + 90 91 1 0 0 0 0 + 91 92 1 0 0 0 0 + 92 93 1 0 0 0 0 + 92 94 2 0 0 0 0 + 89 95 1 6 0 0 0 + 95 96 2 0 0 0 0 + 95 97 1 0 0 0 0 + 97 98 1 0 0 0 0 + 98 99 1 0 0 0 0 + 99100 1 0 0 0 0 +100101 1 0 0 0 0 +101102 2 0 0 0 0 +101103 1 0 0 0 0 + 98104 1 1 0 0 0 +104105 2 0 0 0 0 +104106 1 0 0 0 0 +106107 1 0 0 0 0 +107108 1 0 0 0 0 +108109 1 0 0 0 0 +109110 1 0 0 0 0 +109111 1 0 0 0 0 +107112 1 6 0 0 0 +112113 2 0 0 0 0 +112114 1 0 0 0 0 +114115 1 0 0 0 0 +115116 1 0 0 0 0 +116117 1 0 0 0 0 +117118 2 0 2 0 0 +118119 1 0 0 0 0 +119120 1 0 0 0 0 +120121 2 0 0 0 0 +121117 1 0 0 0 0 +115122 1 6 0 0 0 +122123 2 0 0 0 0 +122124 1 0 0 0 0 +124125 1 0 0 0 0 +125126 1 0 0 0 0 +126127 1 0 0 0 0 +127128 1 0 0 0 0 +128129 1 0 0 0 0 +129130 1 0 0 0 0 +125131 1 1 0 0 0 +131132 2 0 0 0 0 +131133 1 0 0 0 0 +133134 1 0 0 0 0 +134135 1 0 0 0 0 +135136 1 0 0 0 0 +136137 1 0 0 0 0 +136138 1 0 0 0 0 +134139 1 6 0 0 0 +139140 2 0 0 0 0 +139141 1 0 0 0 0 +141142 1 0 0 0 0 +142143 1 0 0 0 0 +143144 1 0 0 0 0 +144145 1 0 0 0 0 +145146 1 0 0 0 0 +145147 2 0 0 0 0 +142148 1 1 0 0 0 +148149 2 0 0 0 0 +148150 1 0 0 0 0 +150151 1 0 0 0 0 +151152 1 6 0 0 0 +152153 2 0 0 0 0 +152154 1 0 0 0 0 +154155 1 0 0 0 0 +155156 1 0 0 0 0 +156157 1 0 0 0 0 +157158 2 0 2 0 0 +158159 1 0 0 0 0 +159160 2 0 1 0 0 +160161 1 0 0 0 0 +160162 1 0 0 0 0 +162163 2 0 2 0 0 +163157 1 0 0 0 0 +155164 1 1 0 0 0 +164165 2 0 0 0 0 +164166 1 0 0 0 0 +166167 1 0 0 0 0 +167168 1 0 0 0 0 +168169 1 0 0 0 0 +169170 1 0 0 0 0 +170166 1 0 0 0 0 +170171 1 1 0 0 0 +171172 2 0 0 0 0 +171173 1 0 0 0 0 +173174 1 0 0 0 0 +174175 1 0 0 0 0 +175176 1 0 0 0 0 +176177 1 0 0 0 0 +177178 1 0 0 0 0 +178179 1 0 0 0 0 +179180 2 0 0 0 0 +179181 1 0 0 0 0 +174182 1 6 0 0 0 +182183 2 0 0 0 0 +182184 1 0 0 0 0 +184185 1 0 0 0 0 +185186 1 1 0 0 0 +186187 2 0 0 0 0 +186188 1 0 0 0 0 +188189 1 0 0 0 0 +189190 1 0 0 0 0 +190191 1 0 0 0 0 +191192 2 0 0 0 0 +191193 1 0 0 0 0 +189194 1 6 0 0 0 +194195 2 0 0 0 0 +194196 1 0 0 0 0 +196197 1 0 0 0 0 +197198 1 0 0 0 0 +198199 2 0 0 0 0 +198200 1 0 0 0 0 +200201 1 0 0 0 0 +201202 1 0 0 0 0 +202203 2 0 0 0 0 +202204 1 0 0 0 0 +204205 1 0 0 0 0 +205206 1 1 0 0 0 +205207 1 0 0 0 0 +207208 2 0 0 0 0 +207209 1 0 0 0 0 +209210 1 0 0 0 0 +210211 1 0 0 0 0 +211212 2 0 0 0 0 +211213 1 0 0 0 0 +213214 1 0 0 0 0 +214215 1 1 0 0 0 +215216 2 0 0 0 0 +215217 1 0 0 0 0 +217218 1 0 0 0 0 +218219 1 0 0 0 0 +219220 1 0 0 0 0 +220221 1 0 0 0 0 +221217 1 0 0 0 0 +221222 1 1 0 0 0 +222223 1 0 0 0 0 +222224 2 0 0 0 0 +214225 1 0 0 0 0 +225226 1 0 0 0 0 +225227 1 1 0 0 0 +197228 1 1 0 0 0 +228229 1 0 0 0 0 +228230 1 0 0 0 0 +185231 1 0 0 0 0 +231232 1 0 0 0 0 +231233 1 1 0 0 0 +151234 1 0 0 0 0 +234235 1 0 0 0 0 +234236 1 6 0 0 0 + 49 6 1 1 0 0 0 +M END +> +MFCD00133860 + +$$$$ +MFCD00143748 + Mt7.00 09020221442D + +239248 0 0 1 0 0 0 0 0999 V2000 + 22.3784 31.9073 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.0226 31.1425 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 24.0070 31.3179 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.6512 30.5531 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.6357 30.7285 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 4.8985 14.2892 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 + 25.9760 31.6688 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 25.3318 32.4337 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.3473 32.2582 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 25.6721 33.3740 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 2.7602 8.1809 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 + 26.6566 33.5495 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.0279 34.1389 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 25.3682 35.0792 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.3527 35.2546 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 24.7240 35.8441 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 23.7266 35.7725 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.3503 36.6990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.1151 37.3432 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.9642 36.8148 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 25.8907 37.1911 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.6798 36.5769 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 26.0280 38.1816 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 25.6517 39.1081 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.6612 39.2455 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.2849 40.1720 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 24.0470 38.4563 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 26.9545 38.5579 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 27.0919 39.5485 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.3027 40.1627 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 28.0184 39.9248 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 28.8075 39.3105 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.7340 39.6869 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 28.1557 40.9153 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 29.0822 41.2916 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.8713 40.6774 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 29.2196 42.2821 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 28.4304 42.8963 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.5039 42.5200 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.7148 43.1342 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 27.3666 41.5295 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 30.1460 42.6584 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 30.2834 43.6489 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.4943 44.2632 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 31.2099 44.0252 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 31.9990 43.4110 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.3473 45.0158 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 32.2737 45.3921 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 33.0629 44.7779 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 32.4111 46.3826 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 31.6220 46.9968 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.6955 46.6205 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 33.3376 46.7589 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 33.4750 47.7494 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.6858 48.3637 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 34.4014 48.1257 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.5388 49.1163 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.4653 49.4926 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.6027 50.4831 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 36.5292 50.8594 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 36.7693 51.8301 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 37.7667 51.9017 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 38.1430 50.9752 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 38.9079 51.6194 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 + 38.9921 50.4469 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 38.7519 49.4761 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 39.3961 48.7113 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 37.7545 49.4046 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 37.3782 50.3310 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 36.6133 49.6868 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 + 26.2799 29.9636 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.2644 30.1391 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 25.9396 29.0233 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 26.5838 28.2585 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 27.5683 28.4339 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.2435 27.3181 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.2590 27.1427 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 26.8877 26.5533 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 27.8852 26.6249 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.2615 25.6984 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.4966 25.0542 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.6476 25.5825 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 25.7211 25.2062 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.9319 25.8204 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 25.5837 24.2157 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 24.6572 23.8394 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 23.8681 24.4536 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.9416 24.0773 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.1525 24.6915 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.2260 24.3152 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 20.4368 24.9294 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.5742 25.9199 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 19.5103 24.5531 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 24.5199 22.8489 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.3090 22.2347 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 23.5934 22.4726 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 23.4560 21.4820 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 24.2452 20.8678 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.1717 21.2441 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.9608 20.6299 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.8235 19.6394 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 26.8873 21.0062 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 22.5295 21.1057 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.7404 21.7199 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 22.3922 20.1152 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 21.4657 19.7389 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 20.6766 20.3531 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.7501 19.9768 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.9609 20.5910 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.0344 20.2147 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 17.2453 20.8289 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.3826 21.8194 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 16.3188 20.4526 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 21.3283 18.7484 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.1175 18.1342 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 20.4018 18.3721 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 20.2645 17.3816 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 21.0536 16.7673 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.9801 17.1437 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.7693 16.5294 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.6958 16.9057 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.4849 16.2915 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 19.3380 17.0052 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.5489 17.6195 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 19.2006 16.0147 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 18.2742 15.6384 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 17.4850 16.2526 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.1368 14.6479 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.9259 14.0337 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 17.2103 14.2716 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 17.0730 13.2811 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.1465 12.9047 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.3573 13.5190 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 16.0091 11.9142 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 15.0826 11.5379 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 14.6311 12.4302 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.0388 13.2359 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 13.3221 13.9332 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 12.5003 14.5030 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5959 14.9298 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 10.6337 15.2019 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6397 15.3119 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6673 16.3115 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 8.6412 15.2568 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 8.5039 16.2474 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.2930 16.8616 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 7.6655 15.0382 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 6.7390 14.6618 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.1920 13.8247 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 5.8870 14.1382 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 5.1329 13.4814 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 4.4972 12.7095 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.6754 13.2793 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 3.9972 11.8435 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 3.0929 12.2703 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.0103 13.2668 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.4370 14.1712 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.8672 14.9930 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.8707 14.9104 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.4439 14.0060 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.0137 13.1843 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.6466 10.9070 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.4549 9.9255 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.8566 9.0097 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 3.4273 8.9259 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 3.5647 7.9354 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.8632 6.9810 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.9367 6.6047 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.3147 6.0887 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 3.4628 5.5650 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.5833 6.0410 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.7314 5.5173 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.8519 5.9933 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0000 5.4696 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 4.9069 5.2830 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 5.6237 4.5857 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.9880 3.8137 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 6.4455 4.0158 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 5.9455 3.1498 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.9455 3.1498 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.3577 3.9588 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.4067 3.6498 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.4067 2.6498 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.6635 1.9807 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.8714 1.0025 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.8225 0.6935 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.5656 1.3627 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.3577 2.3408 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3499 3.5891 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 8.3121 3.3170 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.1204 2.3355 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 9.3061 3.2070 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 9.2785 2.2073 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.3990 1.7314 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3994 1.7589 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.8757 0.9070 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3517 0.0276 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.3513 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.8750 0.8519 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.3045 3.2620 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 11.2803 3.4807 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5788 2.5263 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.2068 3.8570 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 12.6584 2.9648 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1114 2.1276 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.2192 1.6761 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1641 0.6776 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.0012 0.1307 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.8935 0.5822 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.9486 1.5807 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.0588 4.3807 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 13.8129 5.0375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.5296 4.3402 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 14.4486 5.8094 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 15.2704 5.2396 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.1747 5.6663 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.9965 5.0965 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 16.2573 6.6629 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 14.9486 6.6754 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 15.2992 7.6119 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.2615 7.3398 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 15.4909 8.5934 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 16.4849 8.4834 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.8866 7.5676 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.8805 7.4576 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.2822 6.5418 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.2761 6.4318 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 15.5185 9.5930 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 15.3811 10.5835 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.3569 10.8022 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 2.6823 9.5930 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 2.8875 10.5717 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.7321 9.2813 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 6.0380 15.1267 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 6.9696 15.4902 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.2574 15.7517 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 11.9466 15.8663 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.3108 16.6382 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.9329 16.0309 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 3 4 1 0 0 0 0 + 4 5 1 0 0 0 0 + 5 7 1 0 0 0 0 + 7 8 1 0 0 0 0 + 8 9 2 0 0 0 0 + 8 10 1 0 0 0 0 + 10 12 1 1 0 0 0 + 10 13 1 0 0 0 0 + 13 14 1 0 0 0 0 + 14 15 2 0 0 0 0 + 16 14 1 6 0 0 0 + 16 17 1 0 0 0 0 + 17 18 1 0 0 0 0 + 18 19 1 0 0 0 0 + 19 20 1 0 0 0 0 + 20 16 1 0 0 0 0 + 20 21 1 0 0 0 0 + 21 22 2 0 0 0 0 + 21 23 1 0 0 0 0 + 23 24 1 0 0 0 0 + 24 25 1 0 0 0 0 + 25 26 1 0 0 0 0 + 25 27 2 0 0 0 0 + 23 28 1 6 0 0 0 + 28 29 1 0 0 0 0 + 29 30 2 0 0 0 0 + 29 31 1 0 0 0 0 + 31 32 1 0 0 0 0 + 32 33 1 0 0 0 0 + 31 34 1 1 0 0 0 + 34 35 1 0 0 0 0 + 35 36 2 0 0 0 0 + 35 37 1 0 0 0 0 + 37 38 1 0 0 0 0 + 38 39 1 0 0 0 0 + 39 40 1 0 0 0 0 + 39 41 2 0 0 0 0 + 37 42 1 6 0 0 0 + 42 43 1 0 0 0 0 + 43 44 2 0 0 0 0 + 43 45 1 0 0 0 0 + 45 46 1 1 0 0 0 + 45 47 1 0 0 0 0 + 47 48 1 0 0 0 0 + 48 49 2 0 0 0 0 + 48 50 1 0 0 0 0 + 50 51 1 0 0 0 0 + 51 52 1 0 0 0 0 + 50 53 1 6 0 0 0 + 53 54 1 0 0 0 0 + 54 55 2 0 0 0 0 + 54 56 1 0 0 0 0 + 56 57 1 0 0 0 0 + 57 58 1 0 0 0 0 + 58 59 1 0 0 0 0 + 60 59 1 6 0 0 0 + 60 61 1 0 0 0 0 + 61 62 1 0 0 0 0 + 62 63 1 0 0 0 0 + 63 64 1 1 0 0 0 + 63 65 1 0 0 0 0 + 65 66 1 0 0 0 0 + 66 67 2 0 0 0 0 + 66 68 1 0 0 0 0 + 68 69 1 0 0 0 0 + 69 70 1 1 0 0 0 + 69 60 1 0 0 0 0 + 69 63 1 0 0 0 0 + 5 71 1 6 0 0 0 + 71 72 2 0 0 0 0 + 71 73 1 0 0 0 0 + 73 74 1 0 0 0 0 + 74 75 1 1 0 0 0 + 74 76 1 0 0 0 0 + 76 77 2 0 0 0 0 + 76 78 1 0 0 0 0 + 78 79 1 0 0 0 0 + 79 80 1 0 0 0 0 + 80 81 1 0 0 0 0 + 81 82 1 0 0 0 0 + 82 78 1 0 0 0 0 + 82 83 1 1 0 0 0 + 83 84 2 0 0 0 0 + 83 85 1 0 0 0 0 + 85 86 1 0 0 0 0 + 86 87 1 0 0 0 0 + 87 88 1 0 0 0 0 + 88 89 1 0 0 0 0 + 89 90 1 0 0 0 0 + 90 91 1 0 0 0 0 + 91 92 2 0 0 0 0 + 91 93 1 0 0 0 0 + 86 94 1 6 0 0 0 + 94 95 2 0 0 0 0 + 94 96 1 0 0 0 0 + 96 97 1 0 0 0 0 + 97 98 1 0 0 0 0 + 98 99 1 0 0 0 0 + 99100 1 0 0 0 0 +100101 2 0 0 0 0 +100102 1 0 0 0 0 + 97103 1 1 0 0 0 +103104 2 0 0 0 0 +103105 1 0 0 0 0 +105106 1 0 0 0 0 +106107 1 0 0 0 0 +107108 1 0 0 0 0 +108109 1 0 0 0 0 +109110 1 0 0 0 0 +110111 1 0 0 0 0 +111112 2 0 0 0 0 +111113 1 0 0 0 0 +106114 1 6 0 0 0 +114115 2 0 0 0 0 +114116 1 0 0 0 0 +116117 1 0 0 0 0 +117118 1 0 0 0 0 +118119 1 0 0 0 0 +119120 1 0 0 0 0 +120121 1 0 0 0 0 +121122 1 0 0 0 0 +117123 1 1 0 0 0 +123124 2 0 0 0 0 +123125 1 0 0 0 0 +125126 1 0 0 0 0 +126127 1 6 0 0 0 +126128 1 0 0 0 0 +128129 2 0 0 0 0 +128130 1 0 0 0 0 +130131 1 0 0 0 0 +131132 1 0 0 0 0 +132133 2 0 0 0 0 +132134 1 0 0 0 0 +135134 1 6 0 0 0 +135136 1 0 0 0 0 +136137 1 0 0 0 0 +137138 1 0 0 0 0 +138139 1 0 0 0 0 +139140 1 0 0 0 0 +140141 1 0 0 0 0 +141142 1 0 0 0 0 +142143 2 0 0 0 0 +142144 1 0 0 0 0 +144145 1 1 0 0 0 +145146 1 0 0 0 0 +144147 1 0 0 0 0 +147148 1 0 0 0 0 +148149 2 0 0 0 0 +148150 1 0 0 0 0 +150151 1 0 0 0 0 +151152 1 0 0 0 0 +152153 2 0 0 0 0 +152154 1 0 0 0 0 +154155 1 1 0 0 0 +155156 1 0 0 0 0 +156157 2 0 2 0 0 +157158 1 0 0 0 0 +158159 2 0 2 0 0 +159160 1 0 0 0 0 +160161 2 0 2 0 0 +161156 1 0 0 0 0 +154162 1 0 0 0 0 +162163 1 0 0 0 0 +163164 2 0 0 0 0 +163165 1 0 0 0 0 +165166 1 0 0 0 0 +166167 1 0 0 0 0 +167168 2 0 0 0 0 +167169 1 0 0 0 0 +169170 1 1 0 0 0 +170171 1 0 0 0 0 +171172 1 0 0 0 0 +172173 1 0 0 0 0 +173174 1 0 0 0 0 +169175 1 0 0 0 0 +175176 1 0 0 0 0 +176177 2 0 0 0 0 +176178 1 0 0 0 0 +178179 1 1 0 0 0 +179180 1 0 0 0 0 +180181 2 0 2 0 0 +181182 1 0 0 0 0 +182183 1 0 0 0 0 +183184 2 0 1 0 0 +184185 1 0 0 0 0 +185186 2 0 2 0 0 +186187 1 0 0 0 0 +187188 2 0 1 0 0 +188180 1 0 0 0 0 +188183 1 0 0 0 0 +178189 1 0 0 0 0 +189190 1 0 0 0 0 +190191 2 0 0 0 0 +190192 1 0 0 0 0 +192193 1 1 0 0 0 +193194 1 0 0 0 0 +194195 2 0 2 0 0 +195196 1 0 0 0 0 +196197 2 0 2 0 0 +197198 1 0 0 0 0 +198199 2 0 2 0 0 +199194 1 0 0 0 0 +192200 1 0 0 0 0 +200201 1 0 0 0 0 +201202 2 0 0 0 0 +201203 1 0 0 0 0 +203204 1 1 0 0 0 +204205 1 0 0 0 0 +205206 2 0 2 0 0 +206207 1 0 0 0 0 +207208 2 0 2 0 0 +208209 1 0 0 0 0 +209210 2 0 2 0 0 +210205 1 0 0 0 0 +203211 1 0 0 0 0 +211212 1 0 0 0 0 +212213 2 0 0 0 0 +212214 1 0 0 0 0 +214215 1 1 0 0 0 +215216 1 0 0 0 0 +216217 1 0 0 0 0 +216218 2 0 0 0 0 +214219 1 0 0 0 0 +219220 1 0 0 0 0 +220221 2 0 0 0 0 +220222 1 0 0 0 0 +222223 1 1 0 0 0 +223224 1 0 0 0 0 +224225 1 0 0 0 0 +225226 1 0 0 0 0 +226227 1 0 0 0 0 +222228 1 0 0 0 0 +228229 1 0 0 0 0 +229135 1 0 0 0 0 +229230 2 0 0 0 0 +165231 1 0 0 0 0 +231232 1 0 0 0 0 +231233 1 6 0 0 0 +150234 1 0 0 0 0 +234235 1 0 0 0 0 +234236 1 6 0 0 0 +140237 1 6 0 0 0 +237238 2 0 0 0 0 +237239 1 0 0 0 0 +150 6 1 6 0 0 0 +165 11 1 6 0 0 0 +M END +> +MFCD00143748 + +$$$$ +MFCD00142402 + Mt7.00 09020221462D + +241248 0 0 1 0 0 0 0 0999 V2000 + 23.4701 47.7138 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.6780 46.7357 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.9348 46.0665 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 9.5023 2.3831 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 + 21.9838 46.3756 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.1428 45.0884 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 22.3996 44.4193 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 21.4486 44.7283 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.2406 45.7064 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 20.7054 44.0591 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 20.9133 43.0810 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.7544 44.3682 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 19.0112 43.6990 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.2191 42.7209 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 18.0602 44.0080 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 17.3170 43.3389 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 16.3660 43.6479 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.1580 44.6261 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 15.6228 42.9788 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 15.8307 42.0006 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.0876 41.3315 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.2955 40.3534 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.5524 39.6842 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 16.2466 40.0444 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 14.6718 43.2878 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 13.9286 42.6187 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1365 41.6405 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.9776 42.9277 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 12.6685 43.8787 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.6685 43.8787 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.3595 42.9277 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 42.3399 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 41.4739 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 41.4739 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 40.6079 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 11.1685 40.6079 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6685 41.4739 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6685 41.4739 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1685 42.3399 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6685 43.2059 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6685 43.2059 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 42.3399 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 39.7418 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 38.8758 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 38.8758 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 38.0098 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 12.1685 37.1438 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 36.2777 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 36.2777 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 35.4117 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 11.1685 35.4117 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6685 36.2777 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.0753 37.1913 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.3321 37.8604 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 9.4661 37.3604 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6740 36.3823 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 34.5457 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 33.6796 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 33.6796 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 32.8136 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 13.6685 32.8136 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1685 31.9476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1685 30.9476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.0346 30.4476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.9006 30.9476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.9006 31.9476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.0346 32.4476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 31.9476 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 31.0816 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 31.0816 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 30.2155 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 11.1685 30.2155 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6685 31.0816 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6685 31.0816 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1685 31.9476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.1685 31.9476 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 29.3495 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 28.4835 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 28.4835 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 27.6175 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 13.6685 27.6175 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1685 28.4835 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.1685 28.4835 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 29.3495 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 26.7514 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 25.8854 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 25.8854 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 25.0194 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 11.1685 25.0194 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6685 25.8854 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 26.7514 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6685 27.6175 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6685 27.6175 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1685 26.7514 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6685 25.8854 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 24.1534 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 23.2873 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 23.2873 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 22.4213 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 13.6685 22.4213 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1685 23.2873 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 24.1534 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 15.1685 23.2873 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 21.5553 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 20.6893 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 20.6893 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 19.8232 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 11.1685 19.8232 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6685 20.6893 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6685 20.6893 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1685 21.5553 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1685 19.8232 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 18.9572 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 18.0912 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 18.0912 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 17.2252 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 12.1685 16.3591 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 15.4931 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 15.4931 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 14.6271 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 11.1685 14.6271 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6685 15.4931 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 16.3591 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6685 17.2252 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6685 17.2252 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1685 18.0912 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1685 16.3591 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.1685 16.3591 0.0000 I 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6685 15.4931 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 13.7611 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 12.8950 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 12.8950 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 12.0290 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 12.1685 11.1630 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 10.2970 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 10.2970 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 9.4309 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 8.5649 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 7.6989 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 7.6989 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 6.8329 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 13.6685 6.8329 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1685 7.6989 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.1685 7.6989 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 8.5649 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 5.9668 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 5.1008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 5.1008 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 4.2348 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 12.6685 3.3688 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 2.5027 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.6685 1.6367 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1685 0.7707 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 4.2348 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6685 5.1008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1685 5.9668 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6685 5.1008 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 9.5324 6.0915 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1340 7.0087 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 8.5029 7.7844 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 7.6859 8.3611 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.7436 8.6960 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 6.9471 9.6751 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 5.7460 8.7642 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.6777 9.7619 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.7669 8.5608 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.8790 8.1007 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.1482 7.4182 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.3725 8.0492 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 2.6286 6.5637 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 2.3588 5.6008 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 1.3681 5.7370 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.9907 6.6630 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0000 6.7992 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 1.6040 7.4529 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 2.3588 4.6008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.3681 4.4646 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 2.6286 3.6379 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.1482 2.7835 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 2.3725 2.1524 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.4381 2.5086 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.6624 1.8775 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.2794 3.4960 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.8790 2.1009 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.3023 1.2840 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.7669 1.6409 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 5.7460 1.4374 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 5.6777 0.4397 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.7796 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 6.7436 1.5056 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.9471 0.5266 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 7.6859 1.8405 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 8.5029 2.4172 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 9.1340 3.1929 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.9884 2.6733 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 9.5324 4.1101 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 8.4687 1.4178 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 7.5861 0.9476 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.3172 0.8885 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 12.0290 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 14.1685 11.1630 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1685 12.8950 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 17.2252 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 14.1685 16.3591 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1685 18.0912 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6685 38.0098 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 14.1685 37.1437 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1685 38.8758 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 17.8522 44.9862 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 18.5954 45.6553 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.9012 45.2952 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 24.0938 44.7794 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.3017 43.8012 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 24.8370 45.4485 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 25.7880 45.1395 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.5312 45.8086 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.3232 46.7868 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 27.4822 45.4996 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 28.2254 46.1687 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 29.1764 45.8597 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.3843 44.8816 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 29.9196 46.5289 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 30.8706 46.2198 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.6138 46.8890 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.4058 47.8671 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 32.5648 46.5800 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 33.3080 47.2491 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 33.1001 48.2272 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.2590 46.9401 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.4669 45.9619 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 35.0022 47.6092 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 35.9803 47.4013 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 36.4803 48.2673 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.8112 49.0105 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.8976 48.6037 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 34.0316 49.1037 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.0316 50.1037 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 33.1656 48.6037 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 28.0174 47.1469 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.7606 47.8160 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.0664 47.4559 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 3 5 1 1 0 0 0 + 3 6 1 0 0 0 0 + 6 7 1 0 0 0 0 + 7 8 1 0 0 0 0 + 8 9 2 0 0 0 0 + 8 10 1 0 0 0 0 + 10 11 1 6 0 0 0 + 10 12 1 0 0 0 0 + 12 13 1 0 0 0 0 + 13 14 2 0 0 0 0 + 13 15 1 0 0 0 0 + 15 16 1 1 0 0 0 + 16 17 1 0 0 0 0 + 17 18 2 0 0 0 0 + 17 19 1 0 0 0 0 + 19 20 1 0 0 0 0 + 20 21 1 0 0 0 0 + 21 22 1 0 0 0 0 + 22 23 1 0 0 0 0 + 22 24 2 0 0 0 0 + 19 25 1 6 0 0 0 + 25 26 1 0 0 0 0 + 26 27 2 0 0 0 0 + 28 26 1 1 0 0 0 + 28 29 1 0 0 0 0 + 29 30 1 0 0 0 0 + 30 31 1 0 0 0 0 + 31 32 1 0 0 0 0 + 32 28 1 0 0 0 0 + 32 33 1 0 0 0 0 + 33 34 2 0 0 0 0 + 33 35 1 0 0 0 0 + 35 36 1 0 0 0 0 + 36 37 1 0 0 0 0 + 37 38 2 0 2 0 0 + 38 39 1 0 0 0 0 + 39 40 2 0 2 0 0 + 40 41 1 0 0 0 0 + 41 42 2 0 2 0 0 + 42 37 1 0 0 0 0 + 35 43 1 1 0 0 0 + 43 44 1 0 0 0 0 + 44 45 2 0 0 0 0 + 44 46 1 0 0 0 0 + 46 47 1 6 0 0 0 + 47 48 1 0 0 0 0 + 48 49 2 0 0 0 0 + 48 50 1 0 0 0 0 + 50 51 1 0 0 0 0 + 51 52 1 0 0 0 0 + 52 53 2 0 2 0 0 + 53 54 1 0 0 0 0 + 54 55 1 0 0 0 0 + 55 56 2 0 0 0 0 + 56 52 1 0 0 0 0 + 50 57 1 1 0 0 0 + 57 58 1 0 0 0 0 + 58 59 2 0 0 0 0 + 58 60 1 0 0 0 0 + 60 61 1 0 0 0 0 + 61 62 1 0 0 0 0 + 62 63 2 0 2 0 0 + 63 64 1 0 0 0 0 + 64 65 2 0 2 0 0 + 65 66 1 0 0 0 0 + 66 67 2 0 2 0 0 + 67 62 1 0 0 0 0 + 60 68 1 6 0 0 0 + 68 69 1 0 0 0 0 + 69 70 2 0 0 0 0 + 69 71 1 0 0 0 0 + 71 72 1 0 0 0 0 + 72 73 1 0 0 0 0 + 73 74 1 0 0 0 0 + 74 75 1 0 0 0 0 + 75 76 1 0 0 0 0 + 71 77 1 1 0 0 0 + 77 78 1 0 0 0 0 + 78 79 2 0 0 0 0 + 78 80 1 0 0 0 0 + 80 81 1 0 0 0 0 + 81 82 1 0 0 0 0 + 82 83 1 0 0 0 0 + 82 84 2 0 0 0 0 + 80 85 1 6 0 0 0 + 85 86 1 0 0 0 0 + 86 87 2 0 0 0 0 + 86 88 1 0 0 0 0 + 88 89 1 0 0 0 0 + 89 90 1 0 0 0 0 + 90 91 2 0 2 0 0 + 91 92 1 0 0 0 0 + 92 93 2 0 2 0 0 + 93 94 1 0 0 0 0 + 94 95 2 0 2 0 0 + 95 90 1 0 0 0 0 + 88 96 1 1 0 0 0 + 96 97 1 0 0 0 0 + 97 98 2 0 0 0 0 + 97 99 1 0 0 0 0 + 99100 1 0 0 0 0 +100101 1 0 0 0 0 +101102 2 0 0 0 0 +101103 1 0 0 0 0 + 99104 1 6 0 0 0 +104105 1 0 0 0 0 +105106 2 0 0 0 0 +105107 1 0 0 0 0 +107108 1 0 0 0 0 +108109 1 0 0 0 0 +109110 1 0 0 0 0 +110111 1 0 0 0 0 +110112 2 0 0 0 0 +107113 1 1 0 0 0 +113114 1 0 0 0 0 +114115 2 0 0 0 0 +114116 1 0 0 0 0 +116117 1 6 0 0 0 +117118 1 0 0 0 0 +118119 2 0 0 0 0 +118120 1 0 0 0 0 +120121 1 0 0 0 0 +121122 1 0 0 0 0 +122123 2 0 2 0 0 +123124 1 0 0 0 0 +124125 2 0 1 0 0 +125126 1 0 0 0 0 +125127 1 0 0 0 0 +127128 1 0 0 0 0 +127129 2 0 2 0 0 +129122 1 0 0 0 0 +120130 1 1 0 0 0 +130131 1 0 0 0 0 +131132 2 0 0 0 0 +131133 1 0 0 0 0 +133134 1 6 0 0 0 +134135 1 0 0 0 0 +135136 2 0 0 0 0 +135137 1 0 0 0 0 +137138 1 0 0 0 0 +138139 1 0 0 0 0 +139140 2 0 0 0 0 +139141 1 0 0 0 0 +141142 1 0 0 0 0 +142143 1 0 0 0 0 +143144 1 0 0 0 0 +143145 1 0 0 0 0 +141146 1 6 0 0 0 +146147 1 0 0 0 0 +147148 2 0 0 0 0 +147149 1 0 0 0 0 +149150 1 0 0 0 0 +150151 1 0 0 0 0 +151152 1 0 0 0 0 +152153 1 0 0 0 0 +149154 1 6 0 0 0 +154155 1 0 0 0 0 +155156 2 0 0 0 0 +157155 1 1 0 0 0 +157158 1 0 0 0 0 +158159 1 0 0 0 0 +159160 1 0 0 0 0 +160161 1 0 0 0 0 +161162 1 0 0 0 0 +162163 1 1 0 0 0 +162164 1 0 0 0 0 +164165 2 0 0 0 0 +164166 1 0 0 0 0 +166167 1 0 0 0 0 +167168 1 0 0 0 0 +168169 2 0 0 0 0 +168170 1 0 0 0 0 +170171 1 0 0 0 0 +171172 1 6 0 0 0 +172173 1 0 0 0 0 +173174 1 0 0 0 0 +173175 2 0 0 0 0 +171176 1 0 0 0 0 +176177 2 0 0 0 0 +176178 1 0 0 0 0 +178179 1 0 0 0 0 +179180 1 6 0 0 0 +180181 1 0 0 0 0 +181182 1 0 0 0 0 +181183 1 0 0 0 0 +179184 1 0 0 0 0 +184185 2 0 0 0 0 +184186 1 0 0 0 0 +186187 1 0 0 0 0 +187188 1 6 0 0 0 +188189 1 0 0 0 0 +187190 1 0 0 0 0 +190191 2 0 0 0 0 +190192 1 0 0 0 0 +192193 1 0 0 0 0 +193194 1 0 0 0 0 +194195 2 0 0 0 0 +194196 1 0 0 0 0 +196157 1 0 0 0 0 +193197 1 0 0 0 0 +197198 1 0 0 0 0 +197199 1 6 0 0 0 +133200 1 0 0 0 0 +200201 1 0 0 0 0 +200202 1 6 0 0 0 +116203 1 0 0 0 0 +203204 1 0 0 0 0 +203205 1 6 0 0 0 + 46206 1 0 0 0 0 +206207 1 0 0 0 0 +206208 1 6 0 0 0 + 15209 1 0 0 0 0 +209210 1 0 0 0 0 +209211 1 6 0 0 0 + 6212 1 1 0 0 0 +212213 2 0 0 0 0 +212214 1 0 0 0 0 +214215 1 0 0 0 0 +215216 1 0 0 0 0 +216217 2 0 0 0 0 +216218 1 0 0 0 0 +218219 1 0 0 0 0 +219220 1 0 0 0 0 +220221 2 0 0 0 0 +220222 1 0 0 0 0 +222223 1 0 0 0 0 +223224 1 0 0 0 0 +224225 2 0 0 0 0 +224226 1 0 0 0 0 +226227 1 0 0 0 0 +227228 1 1 0 0 0 +227229 1 0 0 0 0 +229230 2 0 0 0 0 +229231 1 0 0 0 0 +231232 1 0 0 0 0 +232233 1 0 0 0 0 +233234 1 0 0 0 0 +234235 1 0 0 0 0 +235231 1 0 0 0 0 +235236 1 6 0 0 0 +236237 1 0 0 0 0 +236238 2 0 0 0 0 +219239 1 1 0 0 0 +239240 1 0 0 0 0 +239241 1 0 0 0 0 +193 4 1 1 0 0 0 +M ISO 1 128 125 +M END +> +MFCD00142402 + +$$$$ +MFCD00142397 + Mt7.00 09020221472D + +245249 0 0 1 0 0 0 0 0999 V2000 + 16.9640 35.7185 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.6331 34.9753 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.3241 34.0243 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 16.3459 33.8164 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.9932 33.2811 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 17.6842 32.3301 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 16.7060 32.1222 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.0369 32.8653 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 16.3970 31.1711 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 17.0662 30.4280 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.4189 30.9632 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 15.1099 30.0122 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.7790 29.2690 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1317 29.8042 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 13.4626 30.5474 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.7716 31.4984 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.1025 32.2416 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 14.7498 31.7064 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 13.8227 28.8532 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.8446 28.6453 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.1754 29.3884 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.5355 27.6942 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 13.2047 26.9511 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.8957 26.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.5648 25.2569 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.2558 24.3058 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.9249 23.5627 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5574 27.4863 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 11.2484 26.5352 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.9175 25.7921 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 10.2702 26.3273 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 9.6011 27.0705 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.9101 28.0215 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.8883 28.2294 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.1973 29.1805 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.5281 29.9236 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.5500 29.7157 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.2410 28.7647 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.9612 25.3763 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 8.9831 25.1684 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.3139 25.9115 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 8.6740 24.2173 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 9.3432 23.4742 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.3213 23.6821 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.9905 22.9389 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.6303 24.6331 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.6959 24.0094 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 7.3869 23.0583 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.0560 22.3152 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 6.4087 22.8504 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 6.0997 21.8994 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 5.1216 21.6915 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.4524 22.4346 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 4.8126 20.7404 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 3.8344 20.5325 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 3.5254 19.5814 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.1945 18.8383 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 2.5472 19.3735 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 1.8781 20.1167 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.1871 21.0677 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.5180 21.8109 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.1653 21.2756 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.2382 18.4225 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 1.2601 18.2146 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.5909 18.9577 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 0.9511 17.2635 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 0.0000 16.9545 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0000 15.9545 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.9511 15.6455 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1.5388 16.4545 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 2.5388 16.4545 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.0388 17.3205 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 3.0388 15.5885 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 4.0388 15.5885 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 4.5388 14.7224 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.0388 13.8564 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 5.5388 14.7224 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 6.0388 15.5885 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.0388 15.5885 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.5388 16.4545 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.5388 16.4545 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 7.0388 17.3205 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 6.0388 13.8564 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 7.0388 13.8564 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.5388 14.7224 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 7.5388 12.9904 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 7.0388 12.1244 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.0388 12.1244 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 8.5388 12.9904 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 9.0388 12.1244 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.5388 11.2583 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 10.0388 12.1244 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 10.5388 12.9904 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5388 12.9904 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.0388 13.8564 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.0388 13.8564 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.5388 14.7224 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 10.5388 11.2583 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5388 11.2583 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.0388 12.1244 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 12.0388 10.3923 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 11.5388 9.5263 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.5388 9.5263 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.0388 8.6603 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.5388 7.7942 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 9.0388 8.6603 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 13.0388 10.3923 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 13.5388 9.5263 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.0388 8.6603 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 14.5388 9.5263 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 15.0388 10.3923 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.0388 10.3923 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 15.0388 8.6603 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 16.0388 8.6603 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.5388 9.5263 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 16.5388 7.7942 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 17.5388 7.7942 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 18.0388 6.9282 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.5388 6.0622 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 19.0388 6.9282 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 19.5388 7.7942 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.5388 7.7942 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.0388 8.6603 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 22.0388 8.6603 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.5388 6.0622 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 20.5388 6.0622 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.0388 6.9282 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 21.0388 5.1962 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 20.5388 4.3301 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.5388 4.3301 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.0388 5.1962 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.0388 5.1962 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.5388 4.3301 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.0388 3.4641 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.0388 3.4641 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.0388 5.1962 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 22.5388 4.3301 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.0388 3.4641 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 23.5388 4.3301 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.0388 3.4641 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 25.0388 3.4641 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.5388 4.3301 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 25.5388 2.5981 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.5388 2.5981 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 27.0388 1.7321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.5388 0.8660 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 28.0388 1.7321 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 28.5388 2.5981 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5388 0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.5388 0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.0388 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0388 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5388 0.8660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.5388 0.8660 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 31.0388 1.7321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.5388 2.5981 0.0000 I 0 0 0 0 0 0 0 0 0 0 0 0 + 30.0388 1.7321 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.0388 6.9282 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 15.0388 6.9282 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.5388 6.0622 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 2.5388 14.7224 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 1.5388 14.7224 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.0388 13.8564 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 5.4817 19.9973 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.1727 19.0462 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 6.4598 20.2052 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.7396 23.5936 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 6.0486 24.5446 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.7615 23.3857 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 18.9714 33.4891 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.6405 32.7459 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 19.2804 34.4401 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 20.2585 34.6480 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 20.5675 35.5991 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.8984 36.3422 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 21.5457 35.8070 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 21.8547 36.7581 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 21.1856 37.5012 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.4946 38.4523 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.8255 39.1954 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.1345 40.1465 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.4653 40.8896 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 22.8329 36.9660 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.5020 36.2228 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 23.1419 37.9170 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 24.1200 38.1249 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 24.7891 37.3818 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.7673 37.5897 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.4364 36.8465 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 26.0763 38.5408 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 24.4290 39.0760 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.7599 39.8191 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 25.4072 39.2839 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 25.7162 40.2350 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 26.6943 40.4429 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.3635 39.6997 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 27.0034 41.3939 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 27.9815 41.6018 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 28.6506 40.8587 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.3416 39.9076 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.6725 39.1645 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.1725 38.2985 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 29.1506 38.5064 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.2552 39.5009 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 28.2905 42.5529 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.6214 43.2960 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 29.2687 42.7608 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 29.5777 43.7119 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 28.9086 44.4550 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.2176 45.4061 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5484 46.1492 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.8575 47.1003 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.1883 47.8434 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 30.5558 43.9198 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.2250 43.1766 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 30.8649 44.8708 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.8430 45.0787 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 32.5121 44.3356 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.2031 43.3845 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.8723 42.6414 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.5632 41.6903 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 33.2324 40.9472 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 32.1520 46.0298 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.4829 46.7729 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 33.1302 46.2377 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 33.4392 47.1888 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.4173 47.3967 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.0865 46.6535 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 34.7263 48.3477 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 35.7045 48.5556 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 36.0135 49.5067 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 36.9917 49.7146 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 37.3007 50.6657 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 38.2788 50.8736 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 36.6315 51.4088 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 36.3736 47.8125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 37.3518 48.0204 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 36.0646 46.8614 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 25.0471 40.9781 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.3561 41.9292 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.0689 40.7702 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.9277 33.9049 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 21.9058 34.1128 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.6186 32.9538 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.2878 32.2107 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 3 4 1 1 0 0 0 + 3 5 1 0 0 0 0 + 5 6 1 0 0 0 0 + 6 7 1 0 0 0 0 + 7 8 2 0 0 0 0 + 7 9 1 0 0 0 0 + 9 10 1 6 0 0 0 + 9 11 1 0 0 0 0 + 11 12 1 0 0 0 0 + 12 13 2 0 0 0 0 + 12 14 1 0 0 0 0 + 14 15 1 0 0 0 0 + 15 16 1 0 0 0 0 + 16 17 1 0 0 0 0 + 16 18 2 0 0 0 0 + 14 19 1 1 0 0 0 + 19 20 1 0 0 0 0 + 20 21 2 0 0 0 0 + 20 22 1 0 0 0 0 + 22 23 1 0 0 0 0 + 23 24 1 0 0 0 0 + 24 25 1 0 0 0 0 + 25 26 1 0 0 0 0 + 26 27 1 0 0 0 0 + 22 28 1 6 0 0 0 + 28 29 1 0 0 0 0 + 29 30 2 0 0 0 0 + 29 31 1 0 0 0 0 + 31 32 1 0 0 0 0 + 32 33 1 0 0 0 0 + 33 34 2 0 2 0 0 + 34 35 1 0 0 0 0 + 35 36 2 0 2 0 0 + 36 37 1 0 0 0 0 + 37 38 2 0 2 0 0 + 38 33 1 0 0 0 0 + 31 39 1 1 0 0 0 + 39 40 1 0 0 0 0 + 40 41 2 0 0 0 0 + 40 42 1 0 0 0 0 + 42 43 1 0 0 0 0 + 43 44 1 0 0 0 0 + 44 45 1 0 0 0 0 + 44 46 1 0 0 0 0 + 42 47 1 6 0 0 0 + 47 48 1 0 0 0 0 + 48 49 2 0 0 0 0 + 48 50 1 0 0 0 0 + 50 51 1 1 0 0 0 + 51 52 1 0 0 0 0 + 52 53 2 0 0 0 0 + 52 54 1 0 0 0 0 + 54 55 1 0 0 0 0 + 55 56 1 0 0 0 0 + 56 57 2 0 0 0 0 + 56 58 1 0 0 0 0 + 58 59 1 0 0 0 0 + 59 60 1 0 0 0 0 + 60 61 1 0 0 0 0 + 60 62 1 0 0 0 0 + 58 63 1 1 0 0 0 + 63 64 1 0 0 0 0 + 64 65 2 0 0 0 0 + 66 64 1 1 0 0 0 + 66 67 1 0 0 0 0 + 67 68 1 0 0 0 0 + 68 69 1 0 0 0 0 + 69 70 1 0 0 0 0 + 70 66 1 0 0 0 0 + 70 71 1 0 0 0 0 + 71 72 2 0 0 0 0 + 71 73 1 0 0 0 0 + 73 74 1 1 0 0 0 + 74 75 1 0 0 0 0 + 75 76 2 0 0 0 0 + 75 77 1 0 0 0 0 + 77 78 1 0 0 0 0 + 78 79 1 0 0 0 0 + 79 80 1 0 0 0 0 + 80 81 1 0 0 0 0 + 80 82 2 0 0 0 0 + 77 83 1 6 0 0 0 + 83 84 1 0 0 0 0 + 84 85 2 0 0 0 0 + 84 86 1 0 0 0 0 + 86 87 1 0 0 0 0 + 87 88 1 0 0 0 0 + 86 89 1 1 0 0 0 + 89 90 1 0 0 0 0 + 90 91 2 0 0 0 0 + 90 92 1 0 0 0 0 + 92 93 1 0 0 0 0 + 93 94 1 0 0 0 0 + 94 95 1 0 0 0 0 + 95 96 1 0 0 0 0 + 96 97 1 0 0 0 0 + 92 98 1 6 0 0 0 + 98 99 1 0 0 0 0 + 99100 2 0 0 0 0 + 99101 1 0 0 0 0 +101102 1 0 0 0 0 +102103 1 0 0 0 0 +103104 1 0 0 0 0 +104105 2 0 0 0 0 +104106 1 0 0 0 0 +101107 1 1 0 0 0 +107108 1 0 0 0 0 +108109 2 0 0 0 0 +108110 1 0 0 0 0 +110111 1 0 0 0 0 +111112 1 0 0 0 0 +110113 1 6 0 0 0 +113114 1 0 0 0 0 +114115 2 0 0 0 0 +114116 1 0 0 0 0 +116117 1 1 0 0 0 +117118 1 0 0 0 0 +118119 2 0 0 0 0 +118120 1 0 0 0 0 +120121 1 0 0 0 0 +121122 1 0 0 0 0 +122123 1 0 0 0 0 +123124 1 0 0 0 0 +120125 1 6 0 0 0 +125126 1 0 0 0 0 +126127 2 0 0 0 0 +126128 1 0 0 0 0 +128129 1 0 0 0 0 +129130 1 0 0 0 0 +130131 2 0 2 0 0 +131132 1 0 0 0 0 +132133 2 0 2 0 0 +133134 1 0 0 0 0 +134135 2 0 2 0 0 +135130 1 0 0 0 0 +128136 1 1 0 0 0 +136137 1 0 0 0 0 +137138 2 0 0 0 0 +137139 1 0 0 0 0 +139140 1 0 0 0 0 +140141 1 0 0 0 0 +141142 2 0 0 0 0 +141143 1 0 0 0 0 +143144 1 0 0 0 0 +144145 1 0 0 0 0 +145146 2 0 0 0 0 +145147 1 0 0 0 0 +147148 1 1 0 0 0 +147149 1 0 0 0 0 +149150 1 0 0 0 0 +150151 2 0 2 0 0 +151152 1 0 0 0 0 +152153 2 0 1 0 0 +153154 1 0 0 0 0 +153155 1 0 0 0 0 +155156 1 0 0 0 0 +155157 2 0 2 0 0 +157150 1 0 0 0 0 +116158 1 0 0 0 0 +158159 1 0 0 0 0 +158160 1 6 0 0 0 + 73161 1 0 0 0 0 +161162 1 0 0 0 0 +161163 1 6 0 0 0 + 54164 1 6 0 0 0 +164165 1 0 0 0 0 +164166 1 0 0 0 0 + 50167 1 0 0 0 0 +167168 1 0 0 0 0 +167169 1 6 0 0 0 + 5170 1 1 0 0 0 +170171 2 0 0 0 0 +170172 1 0 0 0 0 +172173 1 0 0 0 0 +173174 1 6 0 0 0 +174175 2 0 0 0 0 +174176 1 0 0 0 0 +176177 1 0 0 0 0 +177178 1 0 0 0 0 +178179 1 0 0 0 0 +179180 1 0 0 0 0 +180181 1 0 0 0 0 +181182 1 0 0 0 0 +177183 1 1 0 0 0 +183184 2 0 0 0 0 +183185 1 0 0 0 0 +185186 1 0 0 0 0 +186187 1 0 0 0 0 +187188 1 0 0 0 0 +188189 1 0 0 0 0 +188190 2 0 0 0 0 +186191 1 6 0 0 0 +191192 2 0 0 0 0 +191193 1 0 0 0 0 +193194 1 0 0 0 0 +194195 1 0 0 0 0 +195196 2 0 0 0 0 +195197 1 0 0 0 0 +197198 1 0 0 0 0 +198199 1 0 0 0 0 +199200 1 0 0 0 0 +200201 2 0 2 0 0 +201202 1 0 0 0 0 +202203 1 0 0 0 0 +203204 2 0 0 0 0 +204200 1 0 0 0 0 +198205 1 6 0 0 0 +205206 2 0 0 0 0 +205207 1 0 0 0 0 +207208 1 0 0 0 0 +208209 1 0 0 0 0 +209210 1 0 0 0 0 +210211 1 0 0 0 0 +211212 1 0 0 0 0 +212213 1 0 0 0 0 +208214 1 1 0 0 0 +214215 2 0 0 0 0 +214216 1 0 0 0 0 +216217 1 0 0 0 0 +217218 1 0 0 0 0 +218219 1 0 0 0 0 +219220 1 0 0 0 0 +220221 1 0 0 0 0 +221222 1 0 0 0 0 +217223 1 6 0 0 0 +223224 2 0 0 0 0 +223225 1 0 0 0 0 +225226 1 0 0 0 0 +226227 1 0 0 0 0 +227228 2 0 0 0 0 +227229 1 0 0 0 0 +229230 1 0 0 0 0 +230231 1 0 0 0 0 +231232 1 0 0 0 0 +232233 1 0 0 0 0 +233234 1 0 0 0 0 +233235 2 0 0 0 0 +230236 1 1 0 0 0 +236237 2 0 0 0 0 +236238 1 0 0 0 0 +194239 1 1 0 0 0 +239240 1 0 0 0 0 +239241 1 0 0 0 0 +173242 1 0 0 0 0 +242243 1 1 0 0 0 +242244 1 0 0 0 0 +244245 1 0 0 0 0 +M ISO 1 156 125 +M END +> +MFCD00142397 + +$$$$ +MFCD00671471 + Mt7.00 09020221482D + +250253 0 0 1 0 0 0 0 0999 V2000 + 41.7380 15.6713 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 41.0309 16.3784 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 41.2898 17.3443 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 41.2898 18.7585 0.0000 H 0 0 0 0 0 0 0 0 0 0 0 0 + 42.2557 17.6031 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 40.5827 18.0514 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 40.5234 19.0497 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 40.3465 20.0339 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 41.3185 20.2688 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 40.0545 20.9903 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 40.9919 21.3385 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 41.7621 20.7008 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 42.6996 21.0490 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 43.4698 20.4112 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 44.4072 20.7594 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 44.5744 21.7454 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 45.1775 20.1217 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 39.6513 21.9054 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 39.1428 22.7665 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 39.9722 23.3251 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 38.5360 23.5613 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 38.8656 24.5055 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 39.8481 24.6921 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 40.5009 23.9345 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 40.1777 25.6362 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 37.8395 24.2788 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 37.0629 24.9089 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 37.6459 25.7214 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 36.2173 25.4428 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 36.7001 26.3185 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 36.1831 27.1745 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 36.6659 28.0502 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.1833 27.1547 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.3145 25.8728 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 34.3672 26.1931 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.6308 27.1577 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 33.3887 26.3991 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 33.5363 27.3881 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.4667 27.7548 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.6143 28.7438 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.5447 29.1105 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 35.6923 30.0995 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 34.9096 30.7219 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 36.6227 30.4662 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 32.3926 26.4879 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.3930 26.4582 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.3043 27.4543 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 30.4040 26.3106 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 30.1980 27.2891 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.9425 27.9568 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.7365 28.9354 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.4810 29.6030 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 31.2750 30.5816 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 30.3246 30.8925 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 32.0195 31.2492 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 29.4394 26.0470 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5127 25.6712 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.0826 26.5740 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 27.6369 25.1884 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.8245 24.6054 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 26.0866 23.9304 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.3691 24.6270 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 25.4338 23.1729 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 24.6390 23.7797 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.7670 24.7715 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 25.3738 25.5663 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.9889 26.4893 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.9971 26.6173 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.3903 25.8225 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.7753 24.8995 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.8752 22.3435 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 24.4185 21.4538 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.5034 21.8570 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 24.0703 20.5164 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 23.8354 19.5444 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.7172 18.5514 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 23.7172 17.5514 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 23.8354 16.5584 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.0703 15.5864 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 24.4185 14.6490 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 24.8752 13.7593 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 24.0141 13.2508 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 25.4338 12.9299 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.0866 12.1724 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 26.8245 11.4974 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 26.1944 10.7209 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 27.6369 10.9145 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 27.1031 10.0689 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.5685 9.1838 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 27.0347 8.3382 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5677 9.1443 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 28.5127 10.4317 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 29.4394 10.0558 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 29.1191 9.1085 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 30.4040 9.7923 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 31.3930 9.6446 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 32.3926 9.6150 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.4222 8.6154 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 33.3887 9.7038 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 33.5363 8.7147 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 32.7536 8.0923 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 34.3672 9.9097 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 35.3145 10.2300 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 35.6904 9.3033 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 36.2173 10.6601 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 36.7001 9.7843 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 37.6999 9.7646 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 38.1827 8.8889 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 38.2169 10.6206 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 37.0629 11.1939 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 37.8395 11.8240 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 38.5144 11.0862 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 38.5360 12.5415 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 39.2935 11.8887 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 39.1069 10.9062 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 39.1428 13.3364 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 39.6513 14.1974 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 40.5410 13.7408 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 40.0545 15.1125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 40.3465 16.0689 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 40.5234 17.0532 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 40.1293 17.9723 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 23.1139 15.2944 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.3828 15.9766 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 22.8887 14.3201 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 21.9323 14.0280 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 21.2011 14.7102 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.2447 14.4182 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.5136 15.1004 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 20.0195 13.4439 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 21.7070 13.0537 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.4381 12.3715 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 20.7506 12.7617 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 20.5253 11.7874 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 19.5689 11.4953 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.8378 12.1775 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 19.3436 10.5210 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 18.3872 10.2289 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 17.6561 10.9112 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.6997 10.6191 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.9686 11.3014 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.4744 9.6448 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.1620 9.2547 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.8931 8.5724 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 17.2056 8.9626 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 16.9803 7.9883 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 17.7114 7.3061 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 18.6678 7.5981 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.3989 6.9159 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.3554 7.2079 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 21.0865 6.5257 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.8612 5.5514 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 22.0429 6.8178 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 16.0239 7.6962 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.2928 8.3785 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 15.7986 6.7219 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 14.8422 6.4299 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 14.1111 7.1121 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.1547 6.8201 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.4236 7.5023 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.4672 7.2103 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 10.7360 7.8925 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.9613 8.8668 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 9.7796 7.6004 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 14.6169 5.4556 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.3481 4.7734 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 13.6605 5.1635 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 13.4353 4.1892 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 12.4789 3.8972 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.2536 2.9229 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.9847 2.2406 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.7595 1.2664 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.8031 0.9743 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 11.5778 0.0000 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 11.0719 1.6565 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.1155 1.3645 0.0000 I 0 0 0 0 0 0 0 0 0 0 0 0 + 11.2972 2.6308 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.1664 3.5070 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 13.9411 2.5327 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 15.1228 3.7991 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 21.2564 11.1051 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.2128 11.3972 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 21.0312 10.1308 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 23.1139 20.8085 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 22.3828 20.1262 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 22.6081 19.1519 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 21.4264 20.4183 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.6953 19.7361 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 19.7389 20.0281 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 19.5136 21.0024 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 19.0077 19.3459 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 19.2330 18.3716 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 20.1894 18.0795 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 18.0513 19.6379 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 17.3202 18.9557 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.5455 17.9814 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 16.3638 19.2477 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 16.1385 20.2220 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.8697 20.9043 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 17.8261 20.6122 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 16.6444 21.8786 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 15.6327 18.5655 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 14.6763 18.8576 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 14.4510 19.8319 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 13.9451 18.1753 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 14.1704 17.2010 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.1268 16.9090 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.3521 15.9347 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 16.3085 15.6426 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 16.5338 14.6683 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 15.8026 13.9861 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 17.4902 14.3763 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.9887 18.4674 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 12.2576 17.7851 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 12.4829 16.8109 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 11.3012 18.0772 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 11.0759 19.0515 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.1195 19.3436 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.8943 20.3179 0.0000 S 0 0 0 0 0 0 0 0 0 0 0 0 + 8.9379 20.6099 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 10.5701 17.3950 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 9.6137 17.6870 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 9.3884 18.6613 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 8.8826 17.0048 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 7.9262 17.2968 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 7.1950 16.6146 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 7.4203 15.6403 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 6.2386 16.9067 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 6.0134 17.8810 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 5.0570 18.1730 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.8317 19.1473 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.8753 19.4394 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.6500 20.4137 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 5.5075 16.2244 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 4.5511 16.5165 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 4.3258 17.4908 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 3.8200 15.8342 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 3.9422 14.8417 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 3.0360 14.4188 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.3538 15.1499 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.8383 16.0247 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 2.4154 16.9309 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 2.9887 17.7502 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1.4191 17.0177 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 0.8458 16.1984 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0 + 0.9962 17.9239 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 0.0000 18.0107 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 9.1078 16.0305 0.0000 C 0 0 3 0 0 0 0 0 0 0 0 0 + 10.0642 15.7384 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + 8.3767 15.3482 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 1 0 0 0 0 + 2 3 1 0 0 0 0 + 3 5 1 1 0 0 0 + 3 6 1 0 0 0 0 + 6 7 1 0 0 0 0 + 7 8 1 0 0 0 0 + 8 9 2 0 0 0 0 + 8 10 1 0 0 0 0 + 10 11 1 1 0 0 0 + 11 12 1 0 0 0 0 + 12 13 1 0 0 0 0 + 13 14 1 0 0 0 0 + 14 15 1 0 0 0 0 + 15 16 2 0 0 0 0 + 15 17 1 0 0 0 0 + 10 18 1 0 0 0 0 + 18 19 1 0 0 0 0 + 19 20 2 0 0 0 0 + 19 21 1 0 0 0 0 + 21 22 1 1 0 0 0 + 22 23 1 0 0 0 0 + 23 24 2 0 0 0 0 + 23 25 1 0 0 0 0 + 21 26 1 0 0 0 0 + 26 27 1 0 0 0 0 + 27 28 2 0 0 0 0 + 27 29 1 0 0 0 0 + 29 30 1 1 0 0 0 + 30 31 1 0 0 0 0 + 31 32 1 0 0 0 0 + 31 33 1 0 0 0 0 + 29 34 1 0 0 0 0 + 34 35 1 0 0 0 0 + 35 36 2 0 0 0 0 + 35 37 1 0 0 0 0 + 37 38 1 1 0 0 0 + 38 39 1 0 0 0 0 + 39 40 1 0 0 0 0 + 40 41 1 0 0 0 0 + 41 42 1 0 0 0 0 + 42 43 2 0 0 0 0 + 42 44 1 0 0 0 0 + 37 45 1 0 0 0 0 + 45 46 1 0 0 0 0 + 46 47 2 0 0 0 0 + 46 48 1 0 0 0 0 + 48 49 1 1 0 0 0 + 49 50 1 0 0 0 0 + 50 51 1 0 0 0 0 + 51 52 1 0 0 0 0 + 52 53 1 0 0 0 0 + 53 54 2 0 0 0 0 + 53 55 1 0 0 0 0 + 48 56 1 0 0 0 0 + 56 57 1 0 0 0 0 + 57 58 2 0 0 0 0 + 57 59 1 0 0 0 0 + 59 60 1 0 0 0 0 + 60 61 1 0 0 0 0 + 61 62 2 0 0 0 0 + 61 63 1 0 0 0 0 + 63 64 1 1 0 0 0 + 64 65 1 0 0 0 0 + 65 66 2 0 2 0 0 + 66 67 1 0 0 0 0 + 67 68 2 0 2 0 0 + 68 69 1 0 0 0 0 + 69 70 2 0 2 0 0 + 70 65 1 0 0 0 0 + 63 71 1 0 0 0 0 + 71 72 1 0 0 0 0 + 72 73 2 0 0 0 0 + 72 74 1 0 0 0 0 + 74 75 1 0 0 0 0 + 75 76 1 0 0 0 0 + 76 77 1 0 0 0 0 + 77 78 1 0 0 0 0 + 78 79 1 0 0 0 0 + 79 80 1 0 0 0 0 + 80 81 1 0 0 0 0 + 81 82 2 0 0 0 0 + 81 83 1 0 0 0 0 + 83 84 1 0 0 0 0 + 84 85 1 0 0 0 0 + 85 86 2 0 0 0 0 + 85 87 1 0 0 0 0 + 87 88 1 1 0 0 0 + 88 89 1 0 0 0 0 + 89 90 1 0 0 0 0 + 89 91 1 0 0 0 0 + 87 92 1 0 0 0 0 + 92 93 1 0 0 0 0 + 93 94 2 0 0 0 0 + 93 95 1 0 0 0 0 + 95 96 1 0 0 0 0 + 96 97 1 0 0 0 0 + 97 98 2 0 0 0 0 + 97 99 1 0 0 0 0 + 99100 1 1 0 0 0 +100101 1 0 0 0 0 + 99102 1 0 0 0 0 +102103 1 0 0 0 0 +103104 2 0 0 0 0 +103105 1 0 0 0 0 +105106 1 1 0 0 0 +106107 1 0 0 0 0 +107108 1 0 0 0 0 +107109 1 0 0 0 0 +105110 1 0 0 0 0 +110111 1 0 0 0 0 +111112 2 0 0 0 0 +111113 1 0 0 0 0 +113114 1 1 0 0 0 +114115 1 0 0 0 0 +113116 1 0 0 0 0 +116117 1 0 0 0 0 +117118 2 0 0 0 0 +117119 1 0 0 0 0 +119120 1 0 0 0 0 +120121 1 0 0 0 0 +121 6 1 0 0 0 0 +121122 2 0 0 0 0 + 79123 1 6 0 0 0 +123124 2 0 0 0 0 +123125 1 0 0 0 0 +125126 1 0 0 0 0 +126127 1 0 0 0 0 +127128 1 0 0 0 0 +128129 1 0 0 0 0 +128130 2 0 0 0 0 +126131 1 6 0 0 0 +131132 2 0 0 0 0 +131133 1 0 0 0 0 +133134 1 0 0 0 0 +134135 1 0 0 0 0 +135136 2 0 0 0 0 +135137 1 0 0 0 0 +137138 1 0 0 0 0 +138139 1 0 0 0 0 +139140 1 0 0 0 0 +140141 1 0 0 0 0 +140142 1 0 0 0 0 +138143 1 6 0 0 0 +143144 2 0 0 0 0 +143145 1 0 0 0 0 +145146 1 0 0 0 0 +146147 1 0 0 0 0 +147148 1 0 0 0 0 +148149 1 0 0 0 0 +149150 1 0 0 0 0 +150151 1 0 0 0 0 +151152 2 0 0 0 0 +151153 1 0 0 0 0 +146154 1 1 0 0 0 +154155 2 0 0 0 0 +154156 1 0 0 0 0 +156157 1 0 0 0 0 +157158 1 0 0 0 0 +158159 1 0 0 0 0 +159160 1 0 0 0 0 +160161 1 0 0 0 0 +161162 1 0 0 0 0 +162163 2 0 0 0 0 +162164 1 0 0 0 0 +157165 1 6 0 0 0 +165166 2 0 0 0 0 +165167 1 0 0 0 0 +167168 1 0 0 0 0 +168169 1 0 0 0 0 +169170 1 0 0 0 0 +170171 2 0 2 0 0 +171172 1 0 0 0 0 +172173 2 0 1 0 0 +173174 1 0 0 0 0 +173175 1 0 0 0 0 +175176 1 0 0 0 0 +175177 2 0 2 0 0 +177170 1 0 0 0 0 +168178 1 6 0 0 0 +178179 2 0 0 0 0 +178180 1 0 0 0 0 +134181 1 1 0 0 0 +181182 1 0 0 0 0 +181183 1 0 0 0 0 + 74184 1 6 0 0 0 +184185 1 0 0 0 0 +185186 2 0 0 0 0 +185187 1 0 0 0 0 +187188 1 0 0 0 0 +188189 1 0 0 0 0 +189190 2 0 0 0 0 +189191 1 0 0 0 0 +191192 1 0 0 0 0 +192193 1 0 0 0 0 +191194 1 6 0 0 0 +194195 1 0 0 0 0 +195196 2 0 0 0 0 +195197 1 0 0 0 0 +197198 1 0 0 0 0 +198199 1 0 0 0 0 +199200 2 0 0 0 0 +199201 1 0 0 0 0 +197202 1 1 0 0 0 +202203 1 0 0 0 0 +203204 2 0 0 0 0 +203205 1 0 0 0 0 +205206 1 0 0 0 0 +206207 1 0 0 0 0 +207208 1 0 0 0 0 +208209 1 0 0 0 0 +209210 1 0 0 0 0 +210211 2 0 0 0 0 +210212 1 0 0 0 0 +205213 1 6 0 0 0 +213214 1 0 0 0 0 +214215 2 0 0 0 0 +214216 1 0 0 0 0 +216217 1 0 0 0 0 +217218 1 0 0 0 0 +218219 1 0 0 0 0 +219220 1 0 0 0 0 +216221 1 1 0 0 0 +221222 1 0 0 0 0 +222223 2 0 0 0 0 +222224 1 0 0 0 0 +224225 1 6 0 0 0 +225226 1 0 0 0 0 +226227 2 0 0 0 0 +226228 1 0 0 0 0 +228229 1 0 0 0 0 +229230 1 0 0 0 0 +230231 1 0 0 0 0 +231232 1 0 0 0 0 +232233 1 0 0 0 0 +228234 1 1 0 0 0 +234235 1 0 0 0 0 +235236 2 0 0 0 0 +237235 1 6 0 0 0 +237238 1 0 0 0 0 +238239 1 0 0 0 0 +239240 1 0 0 0 0 +240241 1 0 0 0 0 +241237 1 0 0 0 0 +241242 1 0 0 0 0 +242243 2 0 0 0 0 +242244 1 0 0 0 0 +244245 1 1 0 0 0 +244246 1 0 0 0 0 +246247 1 0 0 0 0 +224248 1 0 0 0 0 +248249 1 0 0 0 0 +248250 1 1 0 0 0 + 6 4 1 6 0 0 0 +M ISO 1 176 125 +M END +> +MFCD00671471 + +$$$$ diff --git a/examples/art/agg.bmp b/examples/art/agg.bmp new file mode 100644 index 0000000000000000000000000000000000000000..37a4bc9454020229ae6102787dc8bde65d817532 GIT binary patch literal 3126 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,&UROMKI=;9%$#MKI‚|»·´ãßÛßÛ×®ª¥fa\("%]WO°©¡ÖÏƤ“QJ@71&|ukÊĺÁ¼²zukpmcÅÁ¸ÑÌÅtpi@;4ysj‰}PH:SH9šŒzŠxdnYC¦‘x¢r‚mSª•{¥v“d¬›|Ÿp¡p«™yª—vâÛЯœ{°|°{¯œ{°|±ž}³Ÿ~µ¡µ¡´¡€´¡µ¢‚´¡´¡€´¡€´¡€µ¡€µ¡€µ¡€µ¡µ¡ŸŽt›ŠožŽs¦–{§—}§—}¨˜~¨™¥–}¡’y¡’y£”|¤–~§™ª†ªŸ‡ªŸˆ© ˆ¨ ‰§ ‰§¢‹¥¤£¤¢¥’Ÿ¥’¥“š¥••¢“‘ ’Œ†™Œ‚—Š—‡}–†€™‰€š‹™‹|–ˆtŽv‚x’ƒd~ptŒ€xŽ‚Yndp‚y‚’‰Yi_\j`ˆ”‹yƒxHPFfmb˜“€…{BJ?T]PšŽ£¯£ivi8F9P_Q“¤•¾Î¿¨¸ªevhCPDw„y³¾µÞçÞâêâÈÏÈ“™“`ga=D>%,&NKH752(&#  /-+\ZW–“ÎËÇèäàØÔÏ¡œ˜TNI#,& pjcÁ»³ÒÌ×KF/¦–ƒlZE…r\½©’’g€mT·¦‹¤’x“ƒi¸©Ž¤–yœ‹o²¡„¢‘s§–v¬šz«™wâÜЮ›z®›z­šy¬™x¬™x­šy¯œ{²ž{´ }·£º¦…½©ˆ¿«ŠÁ­‹¾ªˆº§…º¦„»¥ƒ¾§…¾¨†½¨…¤’t r¨—{®‚± …± …± …° …¯Ÿƒ¯žƒ®ž„±¡‡³¤‹³¤Œ²¤±¤Œ±¥Ž°¦°¦®¥«£Ž¥ŸŒ£žŠ¡›‰žšˆœ™ˆ™˜ˆ˜™Š•™‹‘™‹‹–‰…’…“ƒ~’|“‚}”„€˜‰™‹z–ˆv“†z™‹h‡yo‚|™Žbzpkƒx…›’fyoTe[Ž„…‡PZQV_U‘˜•‹NWKFOB~ˆ|¦±¥}‰}AOB>M?xˆz²Ã´¶È¸~IZL6F8Zh\œ‘ÇÓÈàêá×áׯ¹°‰€XbZ4>7%! + +963]YV–’Æ¿àÜØßÚÕ¶±¬ojd83,#PKC¤Ÿ—ØÓËÈû†‚yRNFxtm¼º²ÌÈÂ{vq50*PJB–Œ•ŒSH7eVD´¢§’€mXD™„nÀ¬”|dŽ|cÁ¯”¥•z–‡l»«Ž¤”v¢rµ£…¢pª—wª™x¨˜wâÛÏ­šy®›z­šy­šy­šy®›z°{³Ÿ|¶¢~¹¥‚¼¨‡¾ª‰À¬‹À¬Š¾ª‡¼¨†»¦ƒ½§„¬‡Æ°ŒÅ°‹©˜x¥“w¬›€³¢…¶¥‰µ¥ˆ³£†²¡…²¢†²¢†´£‡´£‰µ¥‹¶¦Ž¶§¶¨‘´¨‘³¨‘±¦®¤© Œ¥Š£›ˆ ˜†Ÿ˜†—†›—†—•…•–‡”—‰–ˆ‹“…„€Ž~‘‚•†–ˆz”†v‘„|™Œj‰|mŒœ‘eue}s‡”mwTf\zŠ‰—Ze[PYOˆ‡‘™[dX=G:qzn¥°¤Œ—‹MYM5B6jyk¦·¨·Éº“¥–UfX4D6CRE|‹~­»¯Õâ××äÙÂÎÄ™¤›gsiFQH + + 3/,VROˆ„°¬©ÓÎÊåáÜÑÌÇ•‘‹WSL#3.'kh_¿»³åáÙÁ½¶xtmGC8G9`ob”£–ÆÕÈ×æÚÎÜѬ¹¯ƒ†\i_ &";73WSOyuq©¥ ÒÍÉåàÜ×ÓÍ·³­xtm=91)$MHA›—áÝ×êçàš”C?962,qmf´®§œ•ŒMD:A7*”‰y¿² ‹}j]L8•ƒmŲœ}gwdM¶¤Œ·¥Œ…sZ¨—}³˜˜ˆn§—|¼¬›‹n¬›~²¡‚£‘r°ž~®›{¯œ{âÜЮ›z¯œ{¯œ|¯œ{±ž|µ¡~¹¤¼¨ƒ¾©…Á­‰Â­ŠÀ¬‰¾«ˆÀ¬‹Á­‹Á®ŠÁ­Š¿«ˆÀ¬‰Ã¯ŒÈ´‘®ž­œ´£†¸§Š¹©¹§·¦‹²¢‡¯Ÿ„­¬‚­ž„¯ ‡²¤Œ³¦Žµ¨‘´¨’³§‘²¦‘¯¤Žª¡Œ¥œŠ¥›Š¢˜‡¢˜† ˜„ž—„—„™•„—”„‘‹Š|…†xƒ†w†wˆz‹}Œ|Ž€t‰|{’†q‰~g€u~–s‰€^ul”Š}‘‰Xj`hxo›’mzqFQHjsk•Ÿ–vu@K?NYMŽ™¡« q|p7E8>N@{Œ~°Ã³­À°‘‚IZK0A3DTFv†y¦¶©ÍÝÐÔã×ÄÓÈ¡°¥}‹‚$*% 72.D?;fa]|x©¤ŸÊÅÀÞÚÔÞÚÔÅÀ»‰‚WSL1-&A=6{wqÇľçãÞ»¸³fd_&#?:3‘Š½µª’‡zMA2bTD±£‘ĵ¢~nYiXA¬šƒÃ°™ƒqX„sYò™­œ‚ˆw^¸©À°–™‰n²£‡»ªŸŽq´£„°Ÿ€¨—w´£‚² ~µ¢äÝÒ²Ÿ~²Ÿ~±ž}±ž|³ }·£º¦ƒ¿«†Æ±Ê¶“dz¯‹¿­‰¿¬‰À­‹Ä°Å°ŒÃ¯ŠÃ¯ŠÄ°‹Æ²Ž®°Ÿ‚·¦‰·§‹¸§·¦‹´¤‰²¡ˆ­Ÿ…¬ƒ¬œƒ­…°¡‰³¤´¦µ¨’´¨’²¦°£Ž­¡ŒªžŠ§œŠ¤š‰£š‰¢˜†¡˜…Ÿ—ƒ›”™“–‘€’Ž‰|‰†w…„vƒƒu„v…x|…xz†yq‚uyŒ€v‰~h}r{‘†xƒ^riuˆ„–\lc[kaˆ•Œy…}HTJZd[™‡‘‡MXLCMBz„y¤®£†‘†GTG6D7aqc˜©›µÈ¹œ®Ÿ]o`2D52C5UfXƒ”†²Ä·ÊÚÎËÚϺɾ¬¢GA;TNH`ZUzupŽ‰„¶±¬ÊÅÀåàÚåáÛÌÈ¢ž—gc\<92<82c`[ž›–ÇÄ¿Æÿ†ƒ~<83*%`XO¶­¡½±£}o_PA/r_ͽ©·¥‘n\FxeN°™¶¥{jR˜ˆo˼£¢’y‘‚hƶµ¦Œ™‰nÀ¯”¸¨Š£“tºª‰¯ž}¬›yµ¤±Ÿ|³¡}äÝÑ´¡¶£¶£µ£µ£º¦ƒÀ¬ˆÃ¯ŒÉµ‘Ë·“Ʋ°ŒÀ®Š¿­‰Â¯‹Æ²ÊµÍ·‘θ“˵ɴ¯ž²¡„¸§‹¸¨Ž¹©·§µ¥‹´¤‹±¡ˆ¯Ÿ‡­†®žˆ°¡‹²¤Žµ¦‘¶¨’¶¨’³§‘±¥®¢¬ Œ¨‰¨Š¥›‰¤›ˆ¤š‡¡˜†Ÿ—…•…œ”„—”ŽŠ{†„uƒs€r~rz~qzst{nwt|†{jujv„x~‚`pdkzo‡”ŠhtjUaX|†~‡’ˆU_WLUM‰“š’`h`?F>fnf˜¢™š¤š]h^2>3DRF‚‘…®¾²©»­~‚HYK+=/8J<`qdŠ›ŽµÆºËÜÐÇ×̽ÌÂztn‚{u”Žˆ¨¢œÃ½·ÑËÅäßÙàÛÕÎÊĨ¤~zsURL?<7GE@tqm¨¥¡ÈÄÀ©¥ _[T,&C;1’ˆ|δ® eVD]M:¤“€ÓÁ­ž‹viVA–ƒmμ¥£’{}mU³¤‹Ë½¤–‡n¡’yË»¡«œ¡‘vÄ´˜­œ¦–v¼«‹¬›y°ž|² ~®œy¯yãÜбž}³¡}´¢~µ¢~·¥¼¨…®‹Ç³Éµ’Ì·”̸•É¶’ƴñŲɴ͸’Ò¼•Ô½—к•Ì·‘°ž² ƒ¹§‹º©Ž»«‘¹¨·§Žµ¥Œ´¤Œ²£‹°¡Š° Š±¡‹³¤Ž´¦¶¨’¶©”µ¨“²¦¯¤­¢©žŠ¨‹¦œ‰¥›Š¤›‰¢šˆ ˜‡ž–‡•†™‘‚•~Ž‰{‡„v€~p}p||pz{nz|pwzovzo~vmshpym€‹grfdodƒŽƒt~tR\RnvnŒ•gogFMFlsl—œ–w}vELEKTL††ž¨Ÿ}‡~BNC5B7aod˜¦›²Ã¶š­žfwi7I;(:,;L?dthŽ’²Â·ÉØÎÄÓÉ«¥ž¹³¬ÆÀºÏÉÂâÝÖäßØàÜÕËÈÀ¨¥žˆ…~`^X:83750\YT™–‘Á½¸¹´­€zr?8.5+qfYÀ³¥ÎÁ±€oXH7ueRÅ´ É·£„r]p^H¶¤ŽÌº¤’‚j‹{cɹ¡¾¯–g°¢‰Ë¼¢ v«›󗤔w¯ž€»ª‹ª˜x³¡±ž~°|°{ãÝѳ ¶¤€¸¦‚¸¦‚º¨„¾ª‡Â®‹Æ²È´‘͹–Ó¿›Ð¼—̸“ɵɴͷѻ”Ó½–Ó½–Ñ»•Ï¹”´ µ£…¼ªŽ¾¬‘»«‘¸§Ž¶¥Œ³£Š²¢‰²¢Š²¢‹±¡‹²£Œ³¥µ§‘·ª”¸«–¶©”±¥®¢Ž©ŸŠ¨Š¨žŒ§žŒ¥œŠ¤›Š¡™‰ ˜ˆž˜ˆ›”„–Ž‰z‰„w‚€q}p}{o{znyymyynyyostj|}spsiinc~†{oxm[dYyw}†}V^U]e\‡†y€yHOIW^W“Œ‹ŠSYR?G?jskœ¦ž“ž•Zf\0>3BPEw†z¦·©­¿°ˆ™‹VgZ0A4&6)>MA`qe‰™Ž©¸­¿ÎÃÏÈÁ×ÑÉßÙÒâÜÕßÙÒ×ÓËÀ¼µ¥£œƒ|RPK.+&*'#ROJ†ƒ}»·±Á»´š“‰^UJ9.!WK=¦™ŠÔÇ·²£’l]L]M: |ÔÁ­°Ÿ‰sbLŠyb˺¢¾­—‡w^žuѧ«‚g¿°—À±—œŒqºªŽÁ±”§–xº©Œ¸¦ˆ«™z·¥…³ ´¡€´¡€æßÓº§†À®‹Á¯‹¾¬ˆÀ­‰Å±Å±ŽÄ±Ä²ŽÈµ’Ï»—м—κ•Î¹”к“Ô¾—ÚÄœÛÅÙÃœ×ÁšÕ¿™¹¥…º¨ŠÁ¯’Á¯”¼«‘·§´¤Š²¢‰° ‡°¡‰±¡Š±¢‹³¤µ¦·©”¹«—¹¬˜¶©”±¥¬ ¨ž‹¦œ‰¦œ‹¦œŒ¥œ‹¤Œ¡šŠŸ˜ˆ–‡›•…–€‰|‰„w‚q~|o{ym|ynywlxvlxvmtrh{xowvmgg^vyox|r\_Wjne†}`f]QWNx~uƒ‰‚V^VGNFv{t”š“mrl@H?MUM†‡œ¦}ˆ~BNC.:0P^R†•‰©º­¤µ¨ƒ“†L\O.>1#3'5E:RaVu„y”£™ÜÖÍÚÔËÒÌÄÐËÂÇú²¯¨—”igc962%"+(#PLG†{·²«Êû¯§rh]E:-J>0†xiȺªÌ¾­n\L;yhUÁ¯›Ñ¿ª‘€io^FªšÓ©¡‘xƒsYº«Ì½£—‰ožu˼¢­ž‚žsŵ˜¶¦‡©˜zÀ¯‘±Ÿ¯~¸¦†·¤ƒ¹¦…º§†çáÕ½ª‰½ª‰½ª‡½«ˆÀ­ŠÅ±ŽÇ´Ä±Ã±Æ´Ë·’ѽ—ÖÀšÕ¿™ÖÀ˜Ø™ÜÆàÊ áÊ¢ßÉ¢ÞÈ¢À¬Á¯‘Æ´—IJ–¿­“¹¨Ž´¤Š±¡‰¯ ‡¯¡‰°£‹²¥Žµ¦¸ª”¹¬—»®šº¬˜µ©–°¥’« Ž¨ž‹¥œŠ¦œ‹¤›Š¤œ‹¤Œ¡šŠŸ˜‡œ•†š’„—‚’‹}ˆ„v‚€r~{nzxlyvkxtjwsivqiupgwrj|wpjg_one||tcd\__X{~uqtlMPIdia†‹ƒjohCHA^c]Ž“ˆŽ‡RYQ;C;ene– ˜”ž•fpf5@50;1^ma “¬¼¯¢±¥{Š~HXL,:/!0%,;1DSIapf¹³ª¹³«·²©¯¬¤•“trmGDA+(%&#.+%TPJ‡‚z»´«ÈÀ··®£„ymMA4B6(tgXº­ÕÇ·¦˜†gXE`O<¡|Öů´¡ŒucL…t\É·ŸÆµœŠz`’ƒhξ£ºª‘‚h¶§ÉºŸ ‘u¬ȸš«œ}± ¾­­›|³¡¶£ƒ¶£‚·¤ƒº§†æàÔ¸¥„¸¥„¸¥„º§†½ªˆÀ®ŠÃ±Â°ŒÃ±ŒÆ´Ë·’ѽ•Ø›ÛÅžÜÆžÝÇàÊ¡ãͤåÎ¥ãÍ¥â̦İı”È·šÅ´˜¿¯“º©´¤Œ±¢Š® ‰¯ Š¯¡Œ±£Ž²¥¶©“·«–¹­š¸¬™µ©–°¥“«¡¨žŒ¥›Š¦Œ¦Œ¦œ¤œ¡™Š–†š’ƒ—€•~“‹|Š…x‚s}zmzvkxtixsixrivpguphtle}unqkcid\{xppnfYWOrqi}~uWYQQTLz~v~ƒ{PVOGMFtzt”š”ounBIAENFxy¦††S]S1:05B7drf“¢–§µª ®£~ŒQ_T/<3,#!.%.;3‘Œƒ‘…„zhe`LIE/+'# %!>:5e`Z˜’‹Ã»²ÑȽº°¤†{nTG:E7)m_P©›ŒÕÇ·¼­œ{lZZK8†ta˹¥Ìº£Œycr_H¬š‚ÖÆ­©™€‚sY° †Ò¨£“y™‰oǹœ½¯‘Žq½­’ò–©™|¾­½«Œ°ž~¹§‡¶£ƒ·¤ƒ·¤ƒ¸¥„æßÓ·¤ƒ·¤ƒ·¤ƒ¸¥„º§…¼ª†¾«ˆÀ­‹Ã±Èµ‘κ”ÕÁ™ÛÅÝÇŸÞÈ àÊ¢âÌ£äÎ¥äÎ¥äÎ¥ãͦűIJ”É·›Æ´˜À°”ºª·¦²£‹¯¡Š® Š®ŸŠ¯¡Œ²¤µ¨“¶ª•¸«˜¶ª˜´©—¯¥“¬¢¨ž£šˆ¡˜† —†¢™‰¡˜‰ž—‡š“‚—€“‹}“Š|‰{ˆƒv~q}ymzvkxtixriwpgvofungqibwohvohg`Xtneyum]YRa_W~|uijaJLCdf_„‡€imeDICW]W‰‰‹’ŠX_W9@8T[S‡‡¤œzƒzGPF*5+8D9huj’Ÿ•¦²¨¤°¦„]h`:F=!,$&jg_XUO@=8-)%&"'#;61[VO}wo©¢™È¿¶Í·²¦šˆ{nVI;G9*fWG¢“ƒÒijʻª~k_OD{gȶ¡ÔÀ¬¡yvcK‹x`ȵœÌ¹¡–„k‰x^»ªÌ¼¡ŸŽt˜‡kÅ´˜»«›‹n²¢„Á±”©˜{± ƒÀ®³¡‚¸¦†¼©ˆº§†»¨‡»¨‡»¨‡º§†çàÔ»¨‡¾«ŠÀ­ŒÁ¯ŽÁ¯ŽÀ®‹À®ŠÁ®Ä²‘É·“о˜ÖÁ›ØÂœØÂœÙÂœÙÃÛÅŸÜÆ ÜÇ¡ÛÇ¢ÛÇ£¾¬Ž¿­’ŵ™Å³˜Á²–¾¯“¼­’¹©¶¦µ¥Žµ¥¸¨“»­˜¾±¿²ŸÀ³¡¾²¡»±žµ«š®¤’§ŒŸ–…š‘€–|”Œ{ˆxŽ‡w…w…wŒ„w‹„wˆt„}r{p~wmztjuqgtqfpndlkchj`gi_gh_eh\mncgg]\\RkkbppgWUMZYQvulnkdKHBUTNw{uu{uJOJ7SZTszu‡Ž‰œ¤ž¶°§¾¶¬Ç½±Äº­¿³¥°£•—‰{tebUGQD5NA2fXIŽ€p½¯ŸÖȷ˼«|r`NdSA‹zhÅ´¡ÔÁ®­š†ygR‚pY¹§Ð¾¦¨—~…sZ§–|ÑÀ¦´¤Š‘f²¡…ɹ§—}¢“xô˜¶¦Š§—z¾­¼«´£†À¯‘¿®Ž¾¬À®Ã°Ä²‘ðéãØIJ’ǵ•È¶–ȶ–É·–È·”ʸ–˸˜Ë¸™Ì»™Ò¿œÖßÚÄ ÙÄ ØÞÙÄžÚÅ ÛÈ¢ÛɤÛȤÛȦ½­¾¯“ô˜Â´˜À²–½¯”º«“¸ª‘·§·§·§‘º¬–¾°›Áµ Á¶¢Ã¸¥Á¶¤¿´¢º¯±§•¨žŸ–…š‘€–}•Œ|’‹zˆy…w‹„u‰‚tˆ‚tˆ‚t†sƒ|p~wl{ujwshushrpfmmbijagi`fi_de[hi^mme^_V``Xsrjfe\RPGecZzxp_\TFE=\_XyxjoiAG@dTCcTCj[KvhX†xhž€¶¦—;¯ØÊ»ÕƸ»¬›Œ{xhXk[Ko^ªš‰ÔñÓñ°žŒ‚p^p\¬›‡ÔïǶ¡™‡rŒ{d·§Òª°¡‰–‡n¶§ÐÀ¦³£‰¥–{´™Ãµš® †½°”ǹœ¼®‘ó•Ç·šÅµ™Åµ™Åµ™Ç¶šÊºžË»ŸÌ¼ íèÞ̾¡Ë¼ Ì¼ Î¾¡Í¾ Î¿¡ÑÁ¢Ñ¤Ñ£ÑÁ¢ÒäÒäÔÅ¥ÖƦÚɪÜ̬ÝÌ­Ü̬ÛÊ«ÚɪÙȪ¼¬”»­”Á³œÃµ¿²œ¼±›¸­™µ©–²§”±§’²§“´©–·¬š»±Ÿ¿´¢Â¸§Ã¸§À·§»²¡µ¬›¬¤“£›‹œ•„—€•Ž”“Œ‘‹}†zŒ…x‰ƒv„rƒ}p~ym{wjytjvrisphpogmmejjdhicfhcef`ee_bb]jjdkkd\\U`_Xqoib_YNLE_]Vuuncf_DGBLPKormy}x\`[9<7?B=ad`~|€ƒ~^b]:=:),)473SVSsxt…Š†Œ’}…€lsoU]Zm“„rž®Ÿ¹ª›È¹ªÔŶØʺο°¼­žŸ‘„uem]MufV“„s½­œØÈ·ÒÁ°¨—†€o^‚q^«›ˆÑÁ®Ç·£›ŠuŠyd° ‹Ò«ºª”™‰r«ž…ÐÁ©¾¯–¥–}¼­“̽¤µ¨µ©ŽÈº À²˜½¯•Ç¸Ç¸Ç¸žÇ¹ŸÆ¸žÈºŸÉ»¡É»¡Ê¼¢ìçÞʽ¢Ë¾¢Ì¾£Î¿¤ÏÀ¥ÐÁ¦ÒçÒħÒħÔŨÕǪÖȪÖȪÖȪØÈ«ÛÊ­ÜÌ®Ü̯Ü̯ÜÌ®Û̯¼¯—º­–¿³œÂµ ¿´ž¼±œ¹®›´«˜³©–±§–²¨–³©˜·®œ»²¡¾µ¥Â¹©Ã¹ªÂ¹©¾µ¥·¯Ÿ­¦–¤›•†—‘‚•€•”Ž‘Š~‡{‹…z‰ƒy†v†€t‚}q{wmyukusisqhnmfkkdiicghcfhcefadf`bc]bb^kkfdd_XWSdc]omhZXRNKFdb]tup]_ZBC?NPLqroy{w\^[;=::<8Y[W{|xƒ…‚knkHJG+/+*-*7;8SYUnsp‚ˆ…‰„‰Æ¸¥Ê½ªÏÁ°ÓƵÕÇ·ÏÁ°Â´£®ŸšŒ{p`rdTqbRŠ|j­žÒóÝͽǷ¦›‹z‚q_‹ziµ¥“Óñŵ¢œ‹xŠzg¯ŸŠÐÀ«À°›žy§˜ÍÀ©É¼¤«ž…´¦ÎÀ§½°—³¥ŒÅ¸ŸÆ¹ ¼¯—Ä·ŸÇº¡Ç» Ç»¡Ç»¡Ç»¡È»¢È»¢È¼£É½¤ìèßʾ¤Ì¿¥ÍÀ¦ÏÁ§ÒêÒĪÒĪÓŪÔƪ×É®ÙÌ°ÙÌ°ÙË®ÖÈ­ØÉ®ÚʯÜ̱ßϳÞϳÝϳÜϲ¿²œº®™¿´ŸÂ¶¡À¶ ½² ¹¯œµ¬›³ªš±©˜°¨–³«š¸¯¼³¤¿·¨Ä»­Ä»­Ã»«¾¶§¸°¡°©š¦ž‘–‰—‘ƒ•‚’€‹~Ž‰}‹…z‰„y‡‚w…u‚~s{pyvmxulusjqpgnngklejkehjegidfhddfbcea_a\deaije^^ZXWRgfakkeUSNNNIffbqrn[\XBB?MNKnolxyvbcaAA>785LLIopm„wzw]a^[\\xzy€‚svtVZX;?=+0."(&&,*286sa{m[vhWufVn_OqbQvgV„uf™‹{´¥•Î¿¯ØɹÖǶ¿°Ÿœ|†wgŠ{k©š‰Î¿¯Øɹº¬›—ˆw’ƒq´¤“ÓIJô¡¡’~¢’~Ŷ¡Î¿ª²¤Ž¬ŸˆÇº£Í¿©º¬•½±šÐĬȽ¦Çº¤Ì«ËÀªÌÀªÌÁªÌÁ©Ê¿¨ËÀ¨ÌÁ©ÌÁªÏĬÑƯïëãÓÇ°ÒÇ°ÒÇ°ÒǯÒÅ®ÓƯÓƯÓÇ°Õȱ×ʳ×ʳØ˳Ù̳Ü϶ÞÒ¹ÞѸÞѸÞѸÞѸÞÒ¸ÞйÁµ¡»±ž¾´¢Â¸§Á·§¿¶¥º±¡·®Ÿ´«œ±©š²©š²©š´«¸°£¾¶©Ã»®Ä½°Ãº®¾¶ª¹±¥°©¨£–ž™˜“‡”ƒ“‚’ƒŽŠ€‹ˆ~‰…|†ƒz„€w{s{xpwtlurlqpjoohnnilmhknijmiilhgjgeigcgdadc`c`_b^ehedgdUWT[\XlmifgcRQMPPLihfsrp]]ZCB?HHFca_zzwsspTTR999445GGHeffz|{‚‚txw]aaEIH166&,,i]NocTtgX|o`Œ~mš{¯¡Ãµ¤Óŵ×ʹвº¬›¢”ƒ‹|l‡xgžÀ²¢×ɹÒ³²£”•†v˜Šz»¬œÓųÁ³¢¢“‚¤•ƒÆ·£Ñï·©•¬ŸŠÅ¶ ÑîÁ²¾±›ÏíÎÀ¬Ç»¥Î­Í­Í®ÎïÎîÎíÍìÎíÏÄ®ÐůÑÇ°ÒȲðìåÔÉ´ÔÉ´ÔÊ´ÓɳÓɲÔȲÔȲÔɳÖ˵×̶Ø̶Ø̶ÚζÜиÞÒºÞÒºÞÒºÞÒºÞÒºÞÒ»ÞÒ¼À¶£º±ž¼³£Á¸¨Á¸¨½¶¦»³¤¸°¡¶® ²«›²ªš±©›³«·°£¼µ©Ã»®Å½²Ä¼°À¹­º³¨±«Ÿ¨¢—žšŽ˜“ˆ“„’ƒ‹Œˆ‰†}ˆ…|…‚zƒw€|t{xqxvourmrqkqojnojmnjknijnjjmigkiejibgfbfebfc_ba^b_figbdbVWT\^ZklieebOOMOOLffcttq``^EECBA@WWTrsqxxvbccFFG446557HII`bbuxx~‚x||lppY__¢˜Œ¥š®£–¹­ŸÂµ¦ÏÁ°Ñòɻª¿±¡ª–‰y‰{k†xi˜Šz¶¨˜Óŵ×ɺĵ¦¤•†“…u£–†Å·§ÕÇ·½¯Ÿ¡“ƒ§˜‡È¹¨ÓIJº¬š­ŸŒÃ¶¢ÓDZķ¢¾²ÏîÑŰɽ§Í¬ÏįÏįÏÄ°ÐűÑƲÑƱÑDzÑDzÓȳÔɵÕʵÕʵðíåÕ˵Õ˶ÕË·ÕÌ·ÖÌ·ÕÌ·ÖÌ·×͸×͸ØκÙϺÙϺÚϺÚϺÚÑ»ÜÑ»ÞÒ¼ÞÓ½ßÔ¾àÕ¿ÞÔ¿À¸¦º±¡»³£Á¹ªÁ¹ª¿¶©»´¦¹°£µ® ²«°©›°©²«ž·¯£»µ©Â»°ÆÀ´Å¿³Á»°¼¶«²­¢¨£™žš˜”Š’Ž„‘Œƒ‹‚Š‡~ˆ…|…‚zƒ€yƒy€~w}ztxwpvtossmqqlpqmnollokknkhlifkjejiciibgf`ee`dd]a_^a_egf_b`SUT[\ZjlidecPQOLMK_a^qqoefcKLJ<>BGHQVX`egjppmstȼÆÀ»Å¾¹Â»µº³®´­¦©£œ£– ™’š’Šœ”‹¨Ÿ”½³¨ÎÄ·Ôɻȼ¯µª›¨œ­¡“Áµ¨ÓÈ»ÓȺÁµ©¶«žÂ¶©ÓÈ»ÕɽǼ¯Æº­Òƹ×˾ÓǹÔȹÚοÛÐÀÛÐÀÜÐÁÝÒÂÞÔÃàÕÅàÖÅàÖÆà×Çß×Èà×ÉáØÊáÚËâÚÍâÛÍâÛÍõòíâÚÊâÚÊâÚËâÚÌâÛÍáÛÍáÛÍâÛÍáÚÌáÚÌáÚÌâÛÌâÛÍäÜÎäÝÏäÝÏäÜÏäÝÐäÝÐäÝÑäÞÑÊĹſ´Á¼²Ä¾´ÇÁ¸È¸Ŀ¶À¼²¾¹¯»µ­¸²ª¶°©¶°©º³­¼¶°¿º³Â½¶Ã¾¸Â½¸¿ºµ¸³®°«§©¤Ÿ¢œ˜š•’•’ŠŠˆ‰‡‹†…ˆ„‚†‚ƒ~}}}||{zzzxxwvvuttusssrqqqnqplpojnnhlmgklejjdiibgg`fg`ef_de\ab]aacggcffX\\OSSVZZcggehhVZYFJIBFELPP]abgllfkkY^`GLM:?@49;3899?@DIK¦ š¤ž˜Ÿ™“›”š”Ž™“Œ›•¤˜±«¥Ä½·ÓÌÅÖÐÇÎƽÀ¸¯¯¦œ¦œ« “¼±¥ÑƹÕ˽ËÀ³»°£¹¯£ÊÀ³×ÍÀÓȽǼ°É¾²ÖʾØÍÂÔɽÖʾÙÎÂÚÐÃÛÑÄÝÓÅßÔÆá×ÈãÙÊäÚËãÚËãÚËâÚÌâÛÍãÛÍãÜÏäÝÏäÝÐåÝÐåÝÐöóîæÞÏåÞÐäÝÏäÝÏäÝÐãÝÐäÝÑäÝÐäÝÐäÞÑäÞÑåßÑæßÓæàÔæàÔæàÔæáÔçáÕèáÖèáÖçáÖËǼÆÁ¸Ä¿µÄ¿¶ÉÄ»ÊżÇúĿ·¿»³½¸°ºµ®¸²¬¸´­ºµ¯»·±¾º´Á½·Â½¸Â½¸À»¶ºµ±³®«¬§¤¤Ÿœ˜–—’“ŽŒ‘ŒŠŠˆ‹‡…‰…„‡„‚„‚ƒ€€€~}|}|z{yyyxwwvvttsssrprqmqqlpojnnhmlfkkdjidiibhhbggaffaff_cc\`aaeecgg\`aQTTPTT[__dgg`ddQTTCGI@EFJOPW]^dijgln`fgTZ[FLM7=>.45£¢­¤£¯§¦±­¬·²²º½¼ÄÄÄÌÌËÔÐÏØÎÎÕÇÅÌ¿½Á±¯²¨¦©¬ª­»¸ºÌÉÌÓÐÓÌÈ˾»½¸µ¶Â¿¿ÒÎÎÖÔÒÎÊÊÆÀÁÌÈÈÕÑÒÕÑÒÒÍÎÔÏÏÖÒÏÖÒÐ×ÓÐØÓÑÙÕÒÙÖÒÚ×ÔÛØÖÛØÕÛØÖÜÙ×ÜÙ×ÜÙÖÝØÕÞÚÔÞÚÕÞÚÕÞÚÕÞÚÕóòðßÚÕßÚÕÞÚÔÞÚÔÝÙÕÝÙÕÞÙÔÞÚÓÞÚÓÞÚÔÞÚÔÞÚÔßÛÕáÛÕàÚÔàÚÔßÚÓßÙÔßÙÔßÙÓàØÔÆ¿¼Â¼¹À¹¶À¹µÄ¾ºÅÁ¼Ã¿ºÀ¼·¼¸´¹´±·²®´¯­³­®´®¯¶¯¯¹²²¼µµ¾¶¶¿·µ½¶²¶±­¯ª¨§£¢žœœ—••’ŒŽˆ‰Œ…‡‰‚„†ƒ}€|}€|}||~zz}yx}ww{vu{vuzuswsruqptqoqpnoolmmjlkijjhgigefededbddbddacc_aa_``]__YZZ[^]`ca]`_TVULONQTR\^]bfd]baNTTBFF?DDCHHNSS\abdiibgg^ccSYYÅÉÝÉÌàÉÌàÊÍáËÎàÈËÜÅÈÚ½ÁÑ´·È¬°Á§«»¨«·³µÁÁÄÐÌÏÜÏÓßÈÊ×¾¿Ì··Ä½½ÈÊËÕÔÕÞÑÓÙÈÉÏÈÇÏÐÏ×ÖÕÝÔÓÛÒÑÙÔÓÛÖÕÛÖÕØÖÕØÖÖÙ×ÖÚ×ÖÚ×ÖÚ×ÖÚ×ÖÚ×ÖÚØ×ÛØØÜØØÜØØÛÚØÙÚØØÚØØÚØØÚØØÚØØòññÚØØÚØØÚØØÚ×ØÚ×ØÚ×ØÚ×ÖÚ×ÕÚ×ÕÚ×ÕÚ×ÕÚ×ÕÚ×ÕÛÖÓÛÖÓÛÖÓÚÕÑÚÕÑÚÕÑÚÕÑÛÔÑýº¿¹¶½·´»µ³¿¹·Â½»À¼¹½º·¹¶³¶²¯³®¬¯«©®ªª®©ª°ª«´¬­¸®°º°²»²²¹²±³®¯«©¬ ¡§–™¡‘š…ˆ”€Žz|‰uvƒrspp~mo{lpympympxopxqqwrrxusuurqtqpsonsnmqmkominiemidkhdifcgebdcacc`ba_``^__]^_]]]\Z[ZWXVVXU\][_`_Y[YNPNKMKORP[]\aed]a`SWVFJJ>BB<@@@EEGLLMRRSYY¸»Ð´¹Ì²µÊ¯³Æ«¯Á¦ª½£¦¹¢¦¹¥¨¼ª­Áµ¹ËÀÄÔÈÍÜÇÌÜ¿ÃÔ´¸É°µÅ´¶ÆÁÂÏÌÌÙÍÎÙÅÇÑÁÂËÆÇÎÍÍÕÑÏØÎÍÖÏÎ×ÑÐÙÓÑÚÓÒÙÓÓÖÔÓ×ÕÕØÕÕØÕÕØÕÕØÕÕ×ÕÕ×ÕÕ×ÕÕ×ÕÕ×ÕÕ×ÖÕ××ÕÖ×ÕÕ×ÕÕ×ÕÕ×ÕÕ×ÕÕñðð×ÕÕ×ÕÕ×ÕÕÖÓÔÖÓÔÖÓÔ×ÔÓ×ÕÓ×ÕÓ×ÔÒÖÓÑÖÓÑ×ÓÑÙÕÐÚÕÐÚÕÐÙÔÐØÓÏØÓÏÙÓÎÚÓͼ¶¿¹³¼¶±º³®»µ±¾¹¶½¹¶º¶³·³°µ°­°«©­¨¥«¨Ÿ«§ ©¦¢¬©§¯¬®±¯²¯®¶¨©µž ¯”¤€ˆšt}‘hs‰]l†Ud€P`{M]yKZuIXsHVqFVnGWnHVmIVkKWkLXkRZhY]g^`iabjggnjjnijlihgigehecgdafc`ea^b`\a_\_]Z]]Z\\Z[[ZYZYYZWUWTTURVWV[\Z[\ZTVTJMJHJHJNMTXV\__]a`X\[OSSEII;?>5:9499¢¨»£©½£¨¼¥ª¾§¬Á¬±Æ³·Ì¸»Ñ¼¿Õ¿ÃÙ½ÂÖ¸¾Ñ®µÈ©¯Â¥«¾«±Åµ¼Ï¿ÂÔÁÁѼ½Ë¸¹Å»¼ÆÂÃÌÈÉÐÉÈÒÉÇÑÌÊÔÌÊÔÌÊÓÌËÕÎÌÔÏÏÒÑÐÓÒÑÕÒÑÕÒÑÕÒÑÕÒÒÒÒÒÑÒÒÑÒÒÑÒÒÑÒÒÑÒÒÑÔÑÒÔÑÒÔÑÒÔÑÒÔÑÒÔÑÒðïïÔÑÒÔÑÒÔÑÒÓÏÐÒÏÐÒÏÐÓÐÏÓÐÎÓÐÎÒÏÍÒÏÌÒÏÌÒÏÌÕÐÌÕÐÌÕÐÌÖÑÌÖÑÌÖÑÌ×ÐÊØÐÈÁº³½¶¯º³­¸²«·±ª»¶±¼·³¹µ±¶²®²®ª¯ª§¬¦¢©¤¨¥¡¤¤§ «”š¬‰‘¨}‰¥t‚¥p} jy›es•_nYiŠPc†K_‚G[~DWzAUw?Qt>Qr=QsMl=Lj=Jg=Kf=Ke?LcALaEM`IPaOVcV[b]`ccdeddceb_e`\c^Z`]Z_\Y\ZW[ZXYYWXXWVWTUVSUVSRSPQROTURXYWXZVQSQILJEGEEIHMPOTXW]`_\a`W[[PTSGLK¸¼Ñ¹¾Ò»¾Ó¼ÀÔ¿ÃØ¿ÃÙ½ÂØ»¿Ó´¸Í¯´È©­Â¦«¿¨­Á­²Æ´¹Î¹½Óº½Ò´µÊ®°Ã¯°Âµ¶Ç¹»Ì¹¼Ë·ºÈ¼¼Ê¿½ËÀ¿ÍÀ¿ÍÀ¾ÌÁ¿ÎÃÂÎÈÈÏËËÐÍÍÒÍÎÑÍÎÑÎÏÑÎÎÎÍÍËÌÌËÌÌËÎÎÌÎÎÌÎÍÌÐÍÏÐÍÐÐÍÐÐÌÏÐÌÏÐÌÏîíîÐÍÎÐÌÍÐÌÍÏËÌÏËÌÎËËÌÉÈËÈÆËÈÆÊÆÅÉÆÄÉÆÄÊÆÅËÆÆËÆÆËÆÆËÇÇÌÇÇÌÇÇÎÆÅÐƹ±¯´¯­²®¬¯«©®ª¨´®ª¸°¬µ¯ª±­©®©¨«¦¨¤¢©™©Š‘¡u~–fs’_n•^o›`v¢bx¦bw¥]ržXl—SfN`‰GY€DV{BSx?Pt=Mr;Ko:In9Io8Im9Hl:Gj:Fh9Ef7Fh4Fh4De4Cb5A^5B\6CZ9EV=GUGMXQU[[[]_]\`\Z^ZW]YV[XUZXVYWUXVTVURUTQTTQTURRSOOPKNOJRSOUWUWYXSVSJMKCFD@CBCFDHLKLOOOTSRVU¶¹Ï¶¹Îµ¸Í²µÉ¯³Å­±Áª­¾©­¾©­¾¬°Á°³Å¸¹Ì¼½Ð½½Ñ¹ºÍµµÉ°±Å¯²Ç°´Ì´¸Ð´¸Ñ²·Ï°¶Î°´Ë²´È´µÈ¶¶É¶·Ê¶·Ê¶·Ê··È¸ºÆ½¿ÈÀÃÊÄÇËÆÉËÇÊËÈÈÈÇÇÅÆÆÄÆÆÄÈÈÆÈÈÆÈÈÈËÈËÌÈÍÌÈÍËÇÌÊÆËÊÆËìëìÉÆÈÈÅÆÈÄÅÈÄÅÇÃÄÆÂÃÅÁÂÄÀÁ¿ÀÁ½¿À¼¾À¼¾À¼ÀÀ¼ÂÀ¼ÂÀ¼ÂÀ¼ÂÀ¼ÂÀ¼Â»Àĺ¾®¨¬©¦ª§¥©¦£§¦¢¥­£¦²¨§²«¦¬©¨¦§¯—š¬y‚ŸZr–KeŒHbŒMf’Ng–Pi˜SkšUmšTl˜Qh•NeI`‹EZ…AU=Pz;Mw7Ir4Fn2Dl2Cj2Bi1Ah1Ag0@f0?e0?c1?b2?a2>`2>_/;]-;Y+:X,;Y.=X1=T5?P;COCJRORVZWX[WVZWUYVTXVSWUQWUOVSNTRPSRPRRORRLPQIMNHLMJNPMQTQSVSRURNPNILIDGD=@>;=<;?<§«Â¨«Â§ªÁ¨¬Áª¯Â¬±Ã®³Å³·É·»Í¸½Ï¹½Ï¹ºÌ¶·É³´Ç²³Æµ¶Ç¸¹Ë·ºÍµ¹Î´¸Î´¸Î³¸Í±¶Ì±´Ê±²Ç±±Å°±Ä±±Å±±Å±±Å±²Ä²´Ãµ·Ã·ºÃº½Ä¼¿Ä½ÁÄ¿ÀÁÀÀÀÁÁÂÂÂÂÃÂÃÃÂÃÃÂÄÄÀÅÅÀÆÅÀÆÅÀÆÆÁÇÆÁÇëéêÿÁ¾¿Á½¾Á½¾À¼½¿»¼¾¹¾½·¿»¶¾»µ½»¶½»¶¾»¶½»¶º¼¶º¼¶º¼¶º¼¶º¼¶º¼¶º½¶º«£¦©Ÿ¡¨¦››¤™š¤¢¦¢«£¦¯™§q€šSfŠH_ŠC_B_B]ŽB^ŽB]B]E`‘Ic“Jc“Ib‘F_ŽC\‰?V„;Q~7Ly5Iu1Eq.Al,>j+>h+=g+=f+a—=`™ZC^E`‘E_D]ŽAZŠk(YŒB]E_‘E_E_C\Œ>W‡:P5Kz1Fu-Bp,An+?l)=j';g';f':e&8c&8a%7`%5^&5\&4[&4Y&4Y%4X$4W"4T!3R 1R/Q-Q-R"/T'4T+7Q-7K.6C8=DINPVWVWUQVTNURJVPIVNITMIQMHNLGLLEKJEKKELLGMMFNMELKCHH@DE?CD=°´Î²¶Ï²¶Ï²¶Ï³¸Í³¸Ì³¸Ì´¹Í´¹Í´¹ÍµºË¹»Ç¹»Çº¼Ç¼¾Ê¾ÁÌÁÃÏÅÄÍÆÃÊÆÃÊÆÃÊÄÂÉÃÀÇÁ¿Ç¾¿Ê»½È·ºÅ¶¸Ä´·Â²´¿°²Á°°Ç°±Ç°±Å±³Ã³µÂ´·Â··Â¹¸Â»¹Ä¼ºÅ»ºÄ»ºÄ¼ºÃ¿ºÁ¿ºÀ¿ºÀ¿ºÀ¿ºÀ¿ºÀèçè¿»¼Á½¾Â¾¿Â¾¿ÄÀÁÇÃÃÈÅÀȞȞȞȞȞɎÎùϹϹϹϹϹÊļÆŽ¸®¦¸«¦ª¥®‰¤Lf4Xˆ6\‘@c¡Dd¨Bb¥?_›<[–:W˜:V–9U’9UŽ:V‹;WŠ>ZŒA]C^D_‘D^C\?Yˆ;R‚7M}2Hw.Cr-Bo,@n)=k(;g';f':e&9d&8b%7a%6^&5\&5[&5Z&4Y%5Y%4Y&4V&3U&3U#1T"1S!.R,M-J$1K)6M*7J(5F,7F?CLTSUXVSXTKXSHYQGWOHSNHQMHOLGNKFOLGOLGOLFOKCOMDNLDLJCIG@µ¹ÑµºÑµºÑµºÑµ¹Î¶¹Í¶¹Í·ºÎ¸»Ï¸»Ï¹»Í¼½È¼¼Ç»¼ÇººÅ½½ÈÁÁÌÆÅÌÉÈÌÊÉÌÊÉÌÈÇÊÇÆÉÆÅÈÂÃÈ¿Àǽ¾Å»»Ä¸¹Ã¶¶Á´´Ã³²Æ³²Ä²±Ã´³ÃµµÄ··Ä¸·Á¹¸¿º¸Àº¹À¹¸À¹¸Àº¸À½¹À¾¹À¾¹À¿ºÀ¿ºÁ¿ºÁèæ轸½¿º¿À»¾¾º»À¼¼Ã¿¾ÈþËŽÌƽÍƼÍÇ»ÍÇ»ÎǹÒǶÒǶÐǹÏÇ»ÏÇ»ÐǺÒƸÒŹº´³£§¶j{œA\Œ8Z’6[”9]—?`ŸCb¢C`žB_˜B]•>Z—U…9O€5Jy1Ft.Cq,Ao*>l(GC=¶»Ð·¼Ñ·¼Ñ·¼Ð¹»Í¹»Ì¹»Ì»¼Î¼¾Ï¼¾Ï¾¾ÍÁÀÉÁÀÉÁ¿È½¼Å¾½ÆÁÀÈÆÆÉËËÉÌÌËÍÍÌÌÍËÌÍËÌÌËÉÉÇÇÇÆÅÅÆÂÁÅ¿¾Å½¼Å»¹Å¸¶Ä¶´Âµ³Á·µÃ¹·Å»¸Æ»¹Âº¹¾º¹¾º¹¾º¹¾º¹¾º¹¾¼¸¾¼·¾¼·¾½¸¿½¸¿½¸¿èæ轸À¿¹ÀÀ»¿À¼¼Á½»Ã¿»ÉÀ¾ÍÁ¿ÎþÏŽÏÅ»ÏƹÐƶÑȱÐȳÏȶÏȸÏȹÑǸÕŸÔƘŸ¯Tn–7]•8]š=]š?]—=[•A^˜EcœFb›EašD_—C^•A\“@Z‘?Z@Y?Y@YŽAZŽBZŽBZD[ŽD[CZ‹@V‡;Q‚6L{2Gv/Ds-Ap*?m)=j';g&9e&9d$7b#6`$6`%7`%7_$6^$5]"4["4Z#3X$3W$3V$3V$2U"1S 0Q.N,J)F*E"/I'4M(3J)2C06>DEDWRM]RM\OJ[OIXMGXLGWKFVLEUKCSJCQHCPGCLD@JB>IB=¸¾Ð¹¾Ñ¹¾Ñ¹¿Ï¼ÀɽÀǽÀÇÀÃÊÂÆÌÂÆÌÄÆËÇÇÉÇÇÈÇÇÈÉÈÊÉÉÊÉÉÊËËÇÌÎÆÎÏÈÏÐÉÎÏÈÎÏÈÎÏÈÎÏÆÍÎÅËÌÅÉÊÆÆÆÆÂÁþ½Ã»ºÅº¸Å¹·Ã¹·Ä»¹Æ¼ºÇ¾½Ä¾½Â¾½Â¾½Â¾½Â¾½Â¾½ÂÀ¼ÁÀ»ÁÀ»ÁÀ»À¿ºÀ¿ºÀèç鿺ÀÁ¼À¾¿ÄÀ¾Å¾ÇþËþÏÄ¿ÐƾÑǽÑÇ»ÑȹÑÉ·ÏÉ´ÐɳÒdzÔÆ´ÔƶÔƹÉÅÇ”¡¹Ng‹;`’6_š;`œ?^˜@]˜?]—@^˜FcIfŸIežHcœE`˜C^•A\“B\’A[‘AZAZB[BZŽC[ŽD\ŽE\ŽD[Œ@Vˆ;Rƒ7M}3Hw0Et-Bp+?n)=k(FTPPXSL[RHZQF[OEZNEYMFYLFWKFTJDSHCOE@LC>KB<¼ÂѼÂѼÂѼÂÐÀÄÈÁÅÅÁÅÅÃÇÇÅÊÊÅÉÊÇÊÉËÌÈËÌÈËÌÈÌÍÉÌÍÈËÌÈÍÎÇÎÏÇÏÐÈÏÐÈÎÏÇÎÏÇÎÏÆÍÏÂÍÏÁÌÎÂËÍÅÉÊÆÆÆÄÃÃÅÁÀÈ¿¾Ç¾¼Æ¼»Ä¼»Ä¿½ÆÁÀÆÂÁÆÃÂÇÃÂÇÂÁÆÂÁÇÃÂÆÆÂÃÆÂÃÆÂÃÆÁÂÅÁÂÅÁÂêééþÁ¾¾Â¾¼Å½ÇĽÉƼÎƾÒÇ¿ÓÉ¿Ô˽Ô˺Ô˸ÓÌ·ÐÌ·ÓË´×ɳ×Ç·ÖÉÂÉÂņ“­Gkž:b˜7bž8aŸ=`?^—@^™A_š@_™FdKh¡Lh¢JgŸGc›Fa˜D^–D^”B\’@Z@YŽ@X@YBZŽD\E\ŽCZŒ@W‰MC<ÀÆÒÁÈÔÁÈÔÂÈÓÄÉÍÅÉÊÅÉÊÆÊËÆÊËÆÊËÈÊÌÌÌÍÌÌÍÌÌÍÌÌÍÌÌÍÌÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÌÌÍÆÌÍÅÌÍÇÍÍÊÌÌÌËÊÌÈÈÌÆÅÊÄÃÉÃÂÇÁÀŽ¼Â½¼ÂÀ¿ÄÂÁÆÄÃÈÅÄÉÄÃÈÄÃÈÅÄÇÇÄÂÇÃÁÇÃÁÇÃÁÇÄÁÇÄÁëêéÇÃÁÅÁ¿Å½ÈżÉǼËɼÑʾÕËÀÖÍ¿ØϾÙѽÙÑ»ØѺÖÒ»ÚѹÝϺÙÎÆÃÅÑ}Ž¬Gh›>i¬:c¡;b aœ@a›B`œB`œCa›FdžKh¢Nj£Mi¢IežHc›Gb™E_–B]“@Z?XŽ?X@XŒAYŽBZŽCZAX‹@Wˆ=S…:P€6L}3Ix0Et.Dr-Ao+?l)=j)=i(»Â̽ÄͽÄͽÄÍÀÄÊÁÄÊÀÄÊÁÄËÂÅËÂÅËÃÅÌÅÄÍÅÄÍÅÄÍÅÄÍÅÄÍÅÄÎÅÃÍÄÃÍÄÃÍÄÃÍÄÃÍÄÃÍÄÃËÅÅÆÅÆÅÅÅÇÅÄÉÃÂÊÂÀÊÂÀÉÃÂÇÁÁÅÀÀÄÀ¿Ã½½Á¾½Á¿¾ÃÀ¿ÄÂÁÆÃÂÇÄÃÈÄÃÈÅÄÇÇÄÁÇÄ¿ÇÄ¿ÇÄ¿ÇÄ¿ÇÄ¿ëêéÈÅÁÊÇÂËÈÁÌÉ¿Í˾Ï;ÔÍ¿×Í¿ØÏ¿ÚÒ¾ÚÒ¼ÚÓºÚÓ¹ÙÔ¸ÜÒ¹ÞÑÁËÉÌzŽ­>i¢=k±Ci°Ac¢BcŸAcžAdŸ@d BcŸDcŸEcFdKh¢Ok¥Nk¤Lg KfžIdœGb™D_•B\’@Z@YŽ@YŽAYAZAYŒ@X‹@W‰=T†;Q‚8N6L{2Gw0Et.Cq,An*?l*>k)8:CQQQ\WP^UK_SH_SI]SI[RHWOFTLCPI@¶¾Ñ¶¾Ñµ½Ð´¼Ï´¼Ï´¼Ï´¼Ï´¼Ï³»Ï³»Ï´¼Î·½Î·¾Î·½Î¸¾ÎºÀнÃÓÄÅÏÈÅÌÉÆÍÈÆÍÆÄËÆÄËÆÄÊÃÆÈÂÆÇÂÆÇÂÆÇÂÆÇÂÆÇÅÇÉÉÈÍÇÆËÆÅÊÄÃÈÄÃÈÄÃÈÄÃÈÄÃÉÄÃÈÄÃÉÅÄÊÇÆÌÈÇÌÆÈÅÆÈÃÆÈÃÆÈÃÆÈÃÆÈÃëëéÇÄÁÈÅÀÊÇ¿ÎÌÀÏξÐνØϽÜξÛÎÁÙÍÁØÍÁÙÏÂÛÒ¾ÝظÉÔÌy™¶?k¤>j®Ek¬Hk¬Hk¯Df¥Ef¥Hh¦Hg¦Gf£Fe FdœEc›Ec›GeœLi Ql£Sl¢Qj¡PhžNf›Lc˜H_“F]‘E[ŽDZBX‹BXŠAV‡AV†?T„?Sƒ>S‚=Q:N|7Jx5Hu3Fs1Dp/Am,?j,>h,=h,=i,T…>S‚>R=Q€;O}8Kz6Iw4Hu2Fr0Co.Am-@k-@k-@l,?l,?k,?j+=i+=h*>g+=d)S„=R‚Sƒ=Q‚;@^URg\SfZPaVM\SIWPFµÀÕµÁÖ¶ÁÖµÁÕ³ÀгÀÏ´Àг¿Ï²¾Î²¾Î´¾Ï·¾Ñ·¾Ñ·¾Ð¶½Ð·¾Ð¸¿Ñ¹ÂкÃκÃκÄÏ»ÅлÅмÅϾÅͽÃʺÀǺÀǼÂɽÃÊ¿ÃÊÁÃÉÂÃÉÂÄÊÆÈÎÈÉÐÉÊÑËÌÎÍÍÌÎÏÌÎÏÊÎÏÉÑÒÊÓÔÊ×ÔÈÙÕÉÚÖËÛ×ËÛ×ËÛ×ËóñëÞؾßؾßØÀßØÁàØÃáÙÅâ×ËåÖÇçؽàØÀÐÙÖ„£¿Am£>j­Al²Dl²Gn²Jq³Ks²Ls¶Nr»Nn´Nm±Pm¯Rm®Sn­No«MnªQm«Sl©Ql¦Oo£Mm Sk¥Vm¦Vo¦Vp¦Sp£PmžNi›Mf™Jc•I`’F^DZŒBX‰AWˆ@U‡>S„>Sƒ=R‚=Q€;P~8N{7My6Lx6Lw6Lw5Lw5Mv5Ov4Nu4Nu2Ms1Mr1Ms0Lq1Lq2Lp2Kp/Hl*Cg(@d'>a'=_&<^(:[(:Z(8X'6V*9X-;X.:T.8N08K08J-5F$/C"-D&1G)2D.5BDFJa[UbZS_VN[SKWPIµÁ×µÁ×µÁ×µÁ×´ÀÔ³ÀÓ³ÀÓ³ÀÓ³ÀÓ³ÀÓ´ÀÓ¸ÀÓ¸ÀÓ¸ÀÓ¶¾Ò·¿Ò¹ÁÔºÃÒºÄкÄкÄлÅлÅлÅнÄλÂ˹ÀÉ·¾Ç¸¿Ç¹ÀɼÂÊ¿ÂÉ¿ÂÉ¿ÂÊÂÅÌÃÆÍÅÈÏÈÉÍËÊÌÌÌËÍÎÉÎÏÈÏÑÇÑÒÇÔÒÆÖÔÇ×ÕÉØÖÊØÖÊØÖÊòðëÞÓÃÞÓÃßÓÃàÕÅàÕÅàÕÅÞÖÆßÖÁâÖ½ÞÙȱ¾ÈPu¢8j¬Bk¯El¯Fm±Ho³JqµLs¶MsºNr¾No·Qo³Sp°Vo¯Wp­Sq¯Ur°Zp®^q®_u­Yv©Ut¤Xp¨Vn§Wp¦Vr¦Sq£OnžOkœNhšMe—Jb”G`E\ŒBY‰AW‰?U‡=R„=R‚=R‚a*=`(<^-@`/B`2B]3BY2?T1=P,;M&3H#/H#/H%1H(5H-6F>BKYX]]XZYUSVRP¶ÂصÁ×µÁ×µÁײ¾Ù±¼Ù¯º×®º×¯º×®º×°»Õ´¼Ð´¼Ï´¼Ï³»Ï´¼Ï´¼Ï´¼Ï³»Ð³»Ð³»Ï³»Ï´¼Ñ¶¾Ò¶¼Î·¼Î¸¾Ðº¿Ñ»ÀÒ»ÀÒ½ÂÐÁÄËÁÄËÁÄËÂÅÌÄÇÎÆÉÐÈÉÍÉÉËÊÊÉËËÇÍÎÇÏÐÆÑÒÇÓÒÆÔÒÆÔÒÆÔÒÆÔÒÆÒÐÄïîëÓËÉÓËÉÓÌÉÔÍÊÔÍÊÕÍÉÚÏ¿ÖнÎÔЙ¯ÂOpŸAi²@i½Bi°El¯Gn²Ip³JqµLs¶Nt¹Qv»QtµSt²Vt±Yu¯_x±j~´zŠ¹’œÂž¦Æž¨ÉŸÃ}’¹j‚­\v£Vq Wt¤Vt¦Sr¥Rn¢PkOi›Mf—Jb”H_D\ŒBY‹AW‰?Uˆ?T‡>T…=RƒT„=R‚;R€:Q8O}7P}6P|4Oz3Oy2Px2Qy1Sz1Ry/Ry.Rx/Ru0Rs1Su2Su1Rt1Rt1Pr0Os.Mq.Lp-Gk*Dh&Ad%?b(Bc+Db1Gc5Ia4H^0DX,@W):U&5S$3Q$3O&6O(9P-;P>HV\ag_aa\^ZãèñãèñäéñäéñäéïäéðåêðåêñåêðåêðåêñçêñçêñçêñçêñçêñçêñæêïåéíåéíæêíçëîæêîæêíçêìèëíèëíéëíéëíéëíéëîêëîêëîêëîëíïëìïêëîëëíëëìëëëëìêììéìíéííéîíéîíéîíéïîêïîêïíéïîêÖÕÉÖÕÊÖÕÊÖÕÊÖÕÊ×ÔÊßÏÌÙÒÜœ°ÏGs¦:n®Bp·FlµEl°Ho²KrµLt·Nu¸OvºRxºUzºUy¶Xy³^{´hƒ¹ƒšÌ±¿ÝÛâêçêçæçÞâåßÔÜß©¸É—·c£WsœSpžTs¦Ss¨So¥Sm QkPiœPhšLe—Jb“G]D[ŽCYŒBX‹AW‰@U‡?T„?V„>Uƒ;S9R€8R6Q}5R}5T|4U}4V}4V~1T|.Rz0Sw2Tv5Wy6Xz6Xy4Uv1Pt/Ot-Mr,Jo*Hl(Ei$Ae"@c%Bc(Dc/Id4Ld5K`1H[.E\,@\);Z'8Y%7U&8S';T+?U4DSR\bbih_d_ÀÌàÁÌáÁÍáÁÌàÂÌÝÃÌÝÄÍÝÄÍÝÃÌÝÃÌÝÄÍÜÇÐÙÇÐÙÇÐÙÈÑÚÈÒÚÈÒÚÉÑÙÈÏ×ÆÍÕÆÍÕÈÎ×ÈÎÖÇÎÖÉÏÖÊÏÖÊÏÖÊÐ×ÊÐ×ÊÐ×ÊÏÖËÍÓËÍÒËÍÓÌÎÓËÍÒÉËÐÊËÏËÌÎÊÌÍËÍÍÌÎÍÌÎÍÍÎÍÐÏÎÑÏÏÑÏÏÑÏÏÑÏÏÑÏÏÐÎÍÏÎÊÏÎÉÏÎÉÏÎÊÏÏÊÐÏÊÖÏÉÈÌÝl‹¾:n¯;s±Fq³MlµIn³Ho²KrµNu¸PwºQy¼Vz»YyºVx·Y{¹d¸{ŽÀ©µÝÛäïéííêëçéèäåååÜáå°½Ñ~–¾d«Ws PnŸQp£Rq¦Ur¦Wo£TlŸSiœQgšNd—K`“G^D\CZ‹CZŠBWˆ@V†?U…@W†>V„V…=U„;Tƒ:S7S6S5S4S€1S2U€2U1U€2U‚4V‚5V€5V5V}4Uz3Tw0Qv+Mt'Jr%Hr!FoDmDnDmEk#Gi(Hf2Oh7Qf6Ob3Nc2Kb/G`+A\(?\'=\)A]-F^:Pc=MYZdiflk¹Éà¸ÇÞ·ÇÞ¸ÇÞºÇÛºÇÚºÇÚ¼ÉܾÊݾÊݾËÜÀÍÚÀÍÚÀÍÚ¾ÌؾËؾËØ¿ÊÖÁËÖÃÍÙÄÎÙÃÌØÃÌØÃÌØÄÍÙÄÎÙÄÍÙÃÍÙÃÍØÃÍÙÃÌ×ÄÉÓÄÉÓÄÉÓÄÉÓÃÈÒÁÇÑÂÇÎÂÈÍÂÈÍÃÉÎÄÊÏÄÊÏÅÊÏÉÊÑÊÊÑÊÊÑÊËÑÊËÑÊËÑËÌÑÌÍÐÌÍÏÌÎÐÏÐÓÐÑÓÏÑÔÍÔÝŠœÀIl®>q·?u³Jt´Op¹Lr·KrµNu¸Ov¹PwºRy¼Wy¾Zx½Xy¹[}³pŽµ™°ÆÒÞçðòñðîêîëçëèçæäéÉÎÜ–£¾n†²\v¦Uq¡Qo Mm¡Mm¢Up¥Yp¥Wm£UkŸRhPfšMb–I`’F^E\CZ‹@Wˆ>U„;R‚;T‚;Uƒ:U‚7R€6R5R3Q~2Q~1P}1Q}2R1S€3U4V€3T~2T{2Tz1Tx1Tw.Sw(Nw$Lv"JvHsEqEqEoFl#Gk(Jj/Ol3Pk1Ng0Mi/Mh/Lg'D`(Ea(Eb+Jf/Nf7Sg8N[M]ders³ÅÞµÆàµÇàµÆà·ÇݸÇݸÇݹÈÞºÉߺÉß»Êß½Ìß½Ìß½Ìß¼ËÞ¼ËÞ¼ËÞ»ÈÙ¼ÈÖ¿ÊÙÁÍÛÄÐÞÄÐÞÄÐÞÄÐÞÁÍܾÊؾÊØ¿ËÙ¿ËÙÂÌÙÆÎÙÆÎÙÆÎÙÅÍØÅÍØÄÍØÃÌÕÃÌÔÅÎÕÆÏÖÆÏÖÆÏÖÆÏÖÉÎ×ÉÎ×ÉÎ×ËÏØÌÐÙËÐÙÌÑØÍÒ×ÍÒ×ÍÒ×ÏÔØÐÕÙÒØݼËáh‚¶Ekµ?p¸?r®Gs²Nr»Ms¸Mt·Mt·Mt¸Nv¹PwºVx½[x¾[|¼^·r‘·š°ÅÐÝæïñòñïîïìíëéíÔØ婶Ï“¶f¬Zu¥Ws£Rq£Nn¢Ll¡Qn¢Wo¤Wo¤Vl¢TjŸQgœMc—Ja“Ha’G_E]BZŠ>U†;Sƒ:T‚:Uƒ:U‚8T6S€4Q~3P}2P~1P}0O}0P~2S3U1S}/Oz.Ox0Sy1Ty0Tw/Sw*Px&Nw#Lu!KtIsGqGp"Io$Kn&Km*Mm.Pn-Ol,Ll+Ll(Jh$Ec)Lh*Lh.Pk.Qj4Ti7SbAXb\pt­ÂÞ­ÁÝ­ÁÝ­ÁݱÂܲÃÛ²ÃÛ³ÄÝ´ÅÞ´ÅÞµÆ߸Éá¸Éá¸ÉáºËãºËãºËã¼Ëß½ËÛ¼ËÛ¾ÌÜÀÏßÀÏßÁÏßÀÎÞ¿ÍݽÌܼÊÚ»ÉÙ»ÉÚ½ÊÙ¿ÊØ¿Ê×ÀËØÁÌÙÁÌÙÁÌÙÃÎØÄÐÙÆÒÛÇÓÛÇÒÛÇÒÛÇÒÛÉÑÛÊÑÛÉÑÛÈÐÚÈÏÚÈÏÚÇÏØÆÎÕÆÎÔÇÏÕÊÒØÌÔÚÎ×ß¡¸ÙOo±Cj¼Bp»Aq­Gs±Lr¼Mt¹Mt·Mt·Mt·Nu¹PwºVx¼[y¼[|½`‚½s¿’§É¼ÈßÝâíéêðâäìÌÑ⧴рšÁi‡´_z©Yt¤Vr¢Sp£No£Kl¡NjŸSj Ul¢Uk¡RhžOe›Ne™Jb•G_‘D\ŽC[ŒAY‰>V†]~=]<]€7Y}2Uy.Sx,Rx*Qv)Pt'Os&Or'Os(Nu%Kq#Jm$Kl)Qo-Vr-Ur+Sp/Uo2Uj9WfNjs²Æß´Èá³Èá³Èà³Çà²Æß²Æß²Æß³Çà³Çà´Çà·Èà¸Èà¸ÈàºËâºÊâ¸Éá³Æß±Åß³Èâ´Éâ´Èâ´ÉãµÉâ´Éà´Éß´Éà¶Ëâ¸Íã·ÍãºÌà¿ÌÜ¿ÌÜÀÌÜÁÍÞÁÎÞÁÎÞÅÏàÇÏáÇÏáÇÏáÇÏáÇÏáÇÏáÆÎàÅÌÞÃÊÝÅÌÞÆÎàÆÎàÅÏÛÄÐØÆÍÞÈÎÙÅÐÍÂÓÒ³ÊÝcŽ¿;o¯V‹>VŠ?W‹D\E\AYŠAY†?X…?Y†A[ˆ@[‡=X…n?]ŽOhšLe–Jc”Ha‘D^C\‹A]Š?\ˆ=Z‡>[ˆ=[ˆ<[†<]‡>`‰=`‰;_‡9]†8]…6\ƒ5]…3\„2[ƒ0Z‚.X€*T}(U}&U~%T}#S|$T}#RzOwPyOyOxPyPyOxOwQy Pz"Qz#Px*U|1[,W~ MvLu#Ps0Yu;^s ¸ã¡¹ä¡ºå¡ºä¡»Ý¢½Ü¤¿Þ¨Ãâ­Çç²Ìì¶Ïî¸Ïì¸Ïì¸Ïì¸Ïì¸Ïì¸Îë¹ÏëºÏêºÏê¹Îé¸Íè¹ÎéºÏéºÐçºÐç»Ñè»Ñè»Ñè»Ñè¼Ñç½Ðå½Ïå¼Ïå½ÐåÀÓèÃÖëÅÖèÅÕåÅÕåÆÖæÇ×çÅÕåÃÓäÆÖæÆÖçÆ×çÉÙéÈØèÂÓã¾ÒܽÒÜÀÎæÁÍã½ÍÙ·Î㉦ÓGv±Ax¶Dy¸Fx¸Gv¶Jw¸Lw¸NvµOwµQy·S{¹S|ºS|ºU{¹Vz·Vz·W{·X|¸X|¸X|·X|´X|²Y|²Y{±Wz®Vy®Wx¬Xw¬XvªVt©Tq¥Ro£Qn¡Nm¡Lj MgžMd›Kgœ=`“BrDc‘Sl›RlšQk˜Pj–Mf“Id‘Fd‘C`?]Š>^Š?_‹?aŒ=_‰<_ˆ:`ˆ8^‡6]…5\„3[‚1\ƒ2]„4_‡3^†1]†0\„-[ƒ)Zƒ(Zƒ(Z‚(Y‚$V~!S{R{R{S|!V~"W€$Y‚%[ƒ#X"W€&X‚)Z‚/^„2`†1_…/]„+[‚,[€1^|7_w£Á墿䢿䢿㡾᡾ߠ¾ß¡¿à£Áâ¦ÄåªÆç®Çæ®Çæ®Çæ®Çæ®Çæ®Çæ²ÉæµÊåµÊå´Éä´Éä·Ìç»Ðê½Ôë½ÓêºÐç¹Ïæ¸Îå¸Îå·Íä¶Ìã¸Îå¹Ïæ¹Îæ»Ðè¾ÓêÄØêÇÙéÇÙéÈÚêÊÝìÍßîÎáðÎàðÎàðÎàðËÞíÇÚéÃÕä½ÓݺÑܹÉä¸ÆáµÇÚ¯Çäz˜ÎEs³By·Ez¸Gy¸Iw¸LyºNyºOx·Qy·R{¹T|»U}»U}»V}ºX|¹X|¸X|¸X|¸X|¸X|¸V|µW|³X}³X}²W|±W{¯Wz®Xw¬Xv«XuªVs§Ur¦Tq¤Qq¥Oo¥Pk¢PhŸLh>b•!IyIh–VqUpœRl˜Oi•Lf‘HdCbŽ@`Œ=]‰<]ˆ=^Š>a‹=b‹;a‰8`ˆ8`ˆ7`ˆ4^…1\‚.Z.Z‚.[ƒ,Z‚,Z‚-[„.]„.]‚.]‚.^‚+Z€)X})Y}&X~$W}&Z€(\‚'\'\€&\$\„%^ˆ'^ˆ(]†,aˆ.a‡-^„/`†2eŒ0dˆ/`~5bz¥Ãã¤Ãâ¤Ãâ¥Ãã¥Ãã¤Âã¢Áá¢Àà¢Áá£Ââ¥Ââ¦Âà§Âà§Âá§Âá§Âà¦ÁߧÁÞ©ÀÝ©ÀÝ©ÀݪÁݪÁÞ«ÂÝ®ÅÞ¯Çß°Èà²Éá³Êâ³Êã³Êâ³Ëâ¶Îå¹Ñé¼Ôë»ÓêºÒé¼Óæ¿Ôä¿Ôä¿Ôä¿ÕåÀÕåÀÕå½Òâ¼Òá»ÑáºÐà¹ÏÞ¸ÎÞ¶ÏÚ¶ÐܹËè»ÊèµÉ߬Éèp’ËCs´Bw·Ex¹IyºKyºNz»P{»P{¸R|¹S}ºU¼W€½W½W¼X~ºY~ºY}¹X|¸X{·X{·X}¶W~µY~´YµY´X~³Y|°Yy®Yw¬WvªWu©Vt§Us¦Ss¦Rr¦Rp¤Rm¢Om Cg˜+QLj–Vp›TošUn™Tm—Pj”Mh“Gg”Ee’Bc=_Œ;^‹=a@f?gm‹>mŒ=m‹;kŠ;i‡=hƒ>hƒ=iƒ>i…>h…=i„:i‡5hˆ3g†2g†4iˆ6k‰7m‹4lŒ0j/kŽ/l0l2n‘3p“3q”3p’6p:oŠ9l„­Êë«Èé«ÈèªÇç¨Æã©Çã«ÉåªÉåªÈäªÈäªÈäªÈäªÈåªÈå©Çã©Æã©Çã¨Æå¨Åæ¨Åæ¨Åæ¨Åæ«Èé®Ìì°Îë±Ïì³Ñí³Ñí³ÒîµÓð·Ôí¹ÓèºÕé»Öë»Õê»Õê»Õê½Ôê½Óé»ÑçºÐæ»Ñç»ÑçºÑç¹Òç·ÒæµÐåµÏä´ÏäµÏä´Ðã´ÐçµÌòµÌî±Ðä¥Ïé\Œ¾Cv¸K|ÂN}ÂP}¿R}¼V~¼V€½S…½R…¼T„¼V„½Yƒ½Z‚½X„¼V‡¼W‡»Y†»[…»]ƒ»^ƒ»^„¹]„·]ƒ¶]ƒ·^„¶]ƒµ]‚´]ƒ´]‚²\±[¯Z~¯Y}­Z}¬[}«Z|ªXz§Yy§Wx¦Ww¤Vx¡Uw Xy¢[}¥]~¥\}¤\{ ^z›^y˜[w–Yt“Wr’TpUrYvZx‘VwUvTuŽTuŽTs’Ts“Ss”Qr’Qr’Qr’Ps‘NuMt‹Kr‹Jr‹JrŒJsIsŽGsŽGsErŽErEsŽEtBt=rlŠDo‹Ep‰GrŒKvMx’Q{–S~šR}—Q˜R‚šR‚šS„R„N‚œMœLœHšE|”;s‰¶Õë²Ñç°Ïå¯Íä®Ìç®Ìé¯Íê±Ïë±Ïì°Îë¯Îç¯Îá±Ðã³Òå¶Õç¶Õè¶Õè¸Øì¸×íµÔê²Ðæ®Íã¯Íã¯Íä¯Íè­Ëè¬Êæ«Éæ«ÉåªÈä¨Çä¥Èä¦Èä¦Éå§Êæ¨Ëæ¨Êæ©Éæ«Éæ¬Ëè­Ìé¬Ëè¬Ëè¬Ëè©Ëè©Ìè©Ìè©Ìç¨Ëç§Êæ¦Ëä¤Èæ¤Äï¢ÃêžÆà’Ää[“ÉKÀT‡ÃYŠÄ]‹ÄbŽÄcŒÁbŒÀa‹Äa‰ÄaˆÄa…ÁbƒÀc‚Àd‚ºe‚³iƒµm„·o…¸o‚¶sƒ¸w‚¶x€µxµu~²py­py­hp¥mt°kq­ah£_f¡\cž_f M`š7W:[”:\•8Y‘0Pˆ-N†.S‹3Z’0W,S‰)O…,R‡2ZŒ2_Ž%R€:g Jy,W†&P M~MOƒ"T†$W‰!Vˆ$YŠ$\ˆY‚![„[ƒ"]… \„ Y€)^*^‚+_‚,`„,a„*_‚1eˆ1e‡2fˆ4i‹6k9o’=r”Et‘Hw“J|—MšPƒžR…¡T‡ V‡žS†žN‚›H~–>vŽ»Ùî»ÚîºÙí¹Øí·Õí·Ôî·Õî¶ÓíµÓì¶Ôí·Ôë¸Öç»Øé½Ûì¿Üí¿Üí¿Üí¿ÜðÀÝòÂßôÂßôÀÝò¾Ûï»Øî¹×ï¸Öï¶ÔíµÒì´ÒëµÒì³Òì®Ðê«Îè©ÌæªÍçªÍçªÌæ¬Íç¯Îé°Ðë²Ñí³Óî´Óî´Ôî²Óí³Õî´Öï´Öï±Óì­Ïè©Íä¦Ìä§Éê§Èé¤Ëæ™Éìa–ÌT…¿^‹Ã^ŽÆ]Æ[ŒÃZˆÀW…½TºT|·Wy¶\z¸a}½a{¼fz³ky«o~µn}·pz´zµ||­|x­~w­„¹‚y­wp¦ro§vx²ek¥[`œeg¦ca¡_[›d^KX”0h.L„C_˜7S‹/M„1P‡3QŠ-K…9Y’;]”-Q‡*O„(M~Ai0X.W5^?i"Bl Cp Fv,Tƒ,Tƒ(Q*U„ M| P€QOSR€RS€S|W€ ZƒVZ‚"]…#]‡ [†]ˆ ^ˆ#_‡-d‹7i?j…Akƒ5bz,Zr7i‚H}˜M›SƒT†ŸP„›L—C|ÀÜîÀÝîÁÝîÀÜîÀÜîÀÜîÂÞðÅáóÈäöÉå÷ÊåöÊãñÊâñÊãñÊãòÊãòÊãòÉâóÈàóÈàóÈàóÇßòÄÜïÀÙì¿Úì½Ùë¼Øê»×é¼Øê¼Øê¹×êµÖê¶×ë·Øì¸Ùî·Øì¶Öë¶×ì¸ÙíºÚïºÛïºÛï¼Üñ½Ýñ¼Úì¼Ùë¼Ùë¾Úì¿Ûí¾Ûí»Üê·ÞçºÜç¼Ûê¹Ùñ±×úv¢Ða‡ºhŽÂ^ÃQ‹ÁF‚½E~¾Bw¸Bu±Nx¶Vs´Yn±Re©Ma¤nz²rs¥oq«vx¸ŠˆÄ„{«‰zž›‰³…p›t›™~¤Šv¢rhrn¤qi›oi ^]˜SX”CO†n +1_9d>e.T4] Fs>m@q'M(O‚!I|DvAsI{L|$TƒQ~P|P{O{JvLxP{TR}R{!\…"\†U‚S‚]Š\ˆ Z/X}Fd‚JexC^l7T`"BO:K&VlAt‘Dy›K€ŸN‚›N„–HÆáðÆâðÆâðÆáðÅàïÆáðÇãñÉäóÊåôÌçöÎçõÏåóÏåòÏåòÏåòÏåòÏåòÏåôÏäöÏåöÎäõËáòÉÞïÇÝîÇáðÆáðÄßîÃÞíÃÞíÃÞíÁÞî¾Ýð½Üï½Ûï¿Þñ¾Ýñ½Üï¼Ûï¾Üð¿ÞñÁàóÄãöÅäøÇåøÉåôÉäóÉäóÊåôËæõËæõÊçòÊèîÎçíÐæïÎåöÆãýŠ¯Ôa‹¾\ÆM†¾?¸?~¹9s±9n°;m²?i¯Ml³NeªmDrIxGtEq +>j =iDnFqDmNt%Yy&Tl4^q>fz7[m.M[ ;F7E4E7M+d6s?x“J|“U’ÐåðÑæòÓèôÔéõÓèôÓèôÓèôÒçóÒçòÒçòÓæñÕæðÕæïÕæïÕçïÕçðÕçðÕæñÕæóÕæóÕæóÖæôÖæôÕçôÓçóÒçóÒçóÓèôÔéõÔéõÓéöÐè÷ÏçöÎæõÍåóÌåóÌåóËãòÊãñÊãñËãòÌåóÌåóÍåóÐåòÑæñÑæñÑæñÑæñÑæñÑåñÑåîÔäê×äéÖæîÐè÷«Ëâ\Ž¿B»5u«0oŸ6l˜3]‡6d.h.H…?R‘=M‹DW“5Oˆ ,c4gOT|•ƒ ¡ˆƒq†jby|j†©‘²€kŽzf‰´œ½½¡½¢‚œŸ€¤ˆ®h™[JULƒTQ„)>k(R,YBSƒHR„4=o.;m5j6l3i 6l)Av&=r6i8d .Z*X8i/Oƒ3T‰1S„$HwCq Dr%Hv&Iw'Ky)P-V„.X† LznBqEsJyJxCpAnEqErBnFoWw(aw7n€;o„)Ti AP!:F#7C,?M.A!Rl3lŠ6pBvW„–ÕèòÕèò×éôØëõ×êô×êô×êô×éóÖéóÖéóØéòÜëòÝìòÞíôßîôÝìóÜëòÛéòÙçóÙçóÚèóÛéõÛéõÛêõÙëõÙëõÙëõ×êôÖèóÖèóÔèóÑçôÑçôÑçôÒèöÒéöÒéöÓé÷Ôê÷Ôê÷ÓéöÑçõÑçõÑçôÓæñÓæðÓæðÓæðÓæðÓæðÑæôÎç÷ÒæòÔåîÐæðÌè÷°Õë^‘¿=x¯0lšHv[[~tj¨™¡¼§«ÚÆÌ­ž¨s~¶¡§°’£xtˆĎž”i„}an`€b_|4Gh'Q%TMPƒytªqj ie›\dO]—0@y0g6k5h/` .[ ++X +*Y$Dv>]’2Q‡&Gx#Er Cn#Eq Bnno;;nJN‚Zc—ZiSešI_“.E{;TŠ3N)Gy*J|4e(T)S)T*V*Y6g:l/^ -X +-W +/V-Q1Q +2S:\'Mo+Pp<\7V!Cb+Kn+Mu!HoAfzSv:f7c(ILWlàäìôøüóöúóöúòõùòõùòõùòõùòõùòõùòõùòõùòõùòöúó÷ûó÷ûó÷ûó÷ûó÷ûó÷úòöúòõùòõùòöúóöúóöúò÷úñùûðøûï÷úðøúï÷ùîöùïöøñõøñõøòöùóøúðô÷áæê½ÒåPu› +6YDc1c}2Kb%=7')UDF}pt²af¥EMˆIO‚X\ˆ-4bDKy  É€w˜o^zocˆXRu’Ž¤øöýäâê{y†aZnjWt{f~†˜uˆ\?WxWx„l‘LAm57f+-^/6h.:n,i1Z2Db¦«¸úùýúûüúúûúúûùùúùùúùùúùùúùùúùùúùùúùùúùùúùúûúúüúúüúûüûûýûüýûüýûûýûûýûûýúûüùúûùúûùúûúüüúüýúüýúüýûýýùûüöúüôûýéñôÛâæÔÛ߯·¼hpwGSi=[y%[z+nŒC|—4Ui&92(1[>DyadžFFNMƒaV…m˜g`Œ"$QIKv[U|^Psynˆ›”¨ÉÂÓòëößØ㦞°bWohUvaPqL@]cWs_On\FisaƒM>adMu¥ˆµ‡qžRLulq™qpžVRƒ<a•9]“/S‡>p9g8e 2\/S2R3N9O:XhSmyWmzXl~^q‚gx‡jy†gs~]grFNXDKT_isFYf<\pEtŽV‹¨]‰œD|Œ/k4Sl*)?1&. '0Gi!W‚Fr’³ÅÎÏÓÏþýüþýüþýüþýúþû÷ýüøùûûãëÇk}Šjˆ™u¨À?r“?f0Rš¨ºùûýÿýüþýûþýûþýûþýûþýüþýüþýûþýûþýûþýûþýüþýüþþüÿþüÿþüÿþüþþüþýüþýüÿÿýÿÿþÿÿþþþüüûúüûúýüúþýûþýüþýüýüûÿþýþüûó÷ùÌÚ⌚¥rŒo~‰YhsFT`S_qFbz@z–7„ /tŒ(Td$=J '<.OR^Š|~±`XŒ`Tƒ“x£”pš†u BAn25cZW‚aT{±¤¯ýóóûñ÷µ¨¶scxo^x`MjkV{ZMsD@dMLpLEjTFjg^}XQojTz¨‡²¥‡´dV€\[ƒ‹€¯‰{­|r¥to¢ghfk¡eo¥):o%XF]Mh™?\ŒBa‘Gg›Ab™Bc˜@a’;]‰;^‡9_„+_{+^w5\qYq‚s}‰}{„zv{tvwvz|pwzW`eHRZLX`EOT[`cmrr_jlNdn6\pEv:r‚,x†,}+`w0AS<>?4:5"5B'Jdb“¿ÇÊ¿¿¹þýúúüúöþýõÿÿöÿþô÷úÈÌÔz‰“Xr~Rj{Gi€>~™4m&Os8Zzˆ¡ÌÓáÞÙåôñøõûü÷þûýüøÿûõûýôóÿõøÿ÷üþùùþûøþþýüþÿûÿþÿÿþÿÿþÿÿýþþýþþýþþþþþþÿþþÿþüÿþúþýùþüøÿýöÿÿúÿþüÿû÷üù×åè§À̃£´h†—av‡WgvDTdNevHgx9Zj/Zl2o‡.sB~•6]m5LU;MYCSdUcyck‡XWuLCczpŒŽ€†±ˆ~¯'7d1Dp]\…²¥¢ùíÙúòêÄ»ÀuhyhSmˆoŠjQjdRnWNo[UzUJq^MsaXzQJk[BltX‡WJy:>k>GsZZ‡rnz«|v¨wq¤wp¥in 'Bm*U1O{7TƒGc“OkœFo•IlYfŽXq•T‰¢\‘ªe‹¨U SŠ™Tx†Zkwcfnrmqhdc\^XYa^FTT1BFFW[m|~rur{}xEUU>[c&IW&H[?_r7hq/w€1‡—!j}1[e0A;FF9ZTPGOXVcogmq^aZþýùõúøØèé¿ÙÞ¾Þæ ·È]q‰Io†Dz8f‚7iŠ5€¡'f‰%OtF`„cv˜]pP^z{“¦¥ÌÒÈåèñùûüúúúýøøýöýùöÿøùüþþ÷ÿÿýýÿÿüÿþþÿýÿÿýÿÿþÿÿþÿÿþÿÿþþÿþþÿýÿÿúþþõüýàéé¸ÇÊœ½É¤ÁÊ»ÏÑœ³¶iœE{˜7lˆ?`nFYe9DQCQ`Ol8ez.dt Yi)cz5k…8cz,IZ2BNDJUakthxbt}YfrQWg?LZQm|\z“Ws™"8f3Bs:Bl²šœûÜÌþèÞûíèż¹µ¯©æÜÖ¶¢¡yhpZQfPKjLFiOEiUOpH;^T5a[Dt:>k/[/_1Bm/@i=Isjpuv¥sp ir›?d€-Qm4VvKjŽMgUl—YpŽgr‰hp‰U™=¢¢@‡”\iŠOt‡Do{AWePVcZW`^[^VUULMMDLQ6CM*9DGQYty}vunS^V4]a(gv\pPb'JXFajGp}%^r*cw-P\+00K>6RDeƒKn‘1hb‡%f’@y¨-i‘!V|"KpFfˆbXwBl‰/pŠ7ƒ–5pƒ€¡¶ÃÝèÓîõöøÿÿöÿÿòþþüþúÿüýÿúÿýúÿþýÿþýÿÿýÿÿýÿÿýÿÿþÿýÿÿýÿÿþÿûýÿùýÿÓÚÛr‰%Jf;U/M^MhvWvŠ>gƒ?auixz€‡ˆrw{es}m…Flƒ4Ob?Qb7EXRwNfnŒ˜˜®«²Â¯³ïÓÌÿâÊúÜ¿ëÒÅžŒc]kCD_@CeTUyQMlgTqŠhŽ`Hq==c.8`$)V+T1V/U=T{Tj‘EZD[|Edt?\l(DV>WnRhƒVj‡RdSYwMVt6gz#zƒ"j{0Ll#?W1D'5H9;M>:I6/<.(4#!/"5#:"*@NPbyu‚fhkAWX8gqbt^qYiVcMl|Om€<`vKm8IWEBIVNO)))7+B+C 4-1.8.N/O-4W*.Y;^`qXf8R$Nt0u¢.Š·.“¸o…HtwŽœ™“‚cRhZPqZS|YN|A3`I=`A2OŽÊODi08]BFqSDx>9i7=i+8b'd@e5V.Q9\ +:Z=U?[m8DV9;P8;T(/J%@+D-Xn7~0o{5^b:UT4PO*OR;@28"2;$/19DbK\w2GX& ((T$:20 -.81^1C{=H…dj£T`Ž>LzSS…{²†r¤{z¡Uc‚0Oj$WmVhO_%AR:EU8GU?O'av7y‘B{”=f},;T,1K·½Æ5HeMQy`O‚„f uª†t¦SK{+0]&8b8a>e9`9bg’E_•@U’8Q“4O“1L‘3KŽ*F‚Bt!Iz@o5]8NjVbt/?N.< /=#2&4F[i3\j+• Sh, 12 ±Ùî³×ê¼ÝîÀàï»âí¿åô‹­Å7\z$RsQt6[+R+P(K:^}®Õî¾äû»áö½âö¿å÷»àó¹ßó¹ßó¸Þñ´àð³âñ³âñ²àï©Øç¦Ôä±àï•ÃÖk™¯°Þñ®Úï°Ûð´ßô«Øï£Ñê¨Óì²Üó·ßõµÜñµÚî¾ßïÁâò»ßñ·ßô²Þö±Þø¬Ûñª×è¯ÙëµÊ+Jb :U5Pk)[q![o>V *C763#866`-K!=x4I†bk¦pm¦peŸXJ‚h\‘{ªlo›a`’RIyUBhfKgtXo‡mƒ–zŽ™v‡‰wŠlrŠJ_{0Ea'6P"?3©´»#=TWTwu¢†j˜n›|s gf“:Cp#7b">h]#Ci>f 1Z *Q%K8\z¥Å Ñì˜ËåšÈà§Ñè³Ýò¼æú±Üò±Ûó³Þõ£ÓêžÑçŸÒè¥×í¥ØîŸÑè›Ìâ–ÈܘËàšÏåœÔëœÖï—Ñì“Ìë’Èé—Êé¦Õð²Üô¸ÞòÀä÷ºÞñ´Øë­ÓçªÒç¦Ðæ¥Ðè¡Ïå¨Øë®ÛÉ1Of%=V@Wp*TjEZ8N +#;1+*/ +!G@o5\“;u7pDZ’dj£jh¢WOˆNF{sp¡or¡vm¡zb”}VzEh›]}¶u—¹u–¾x”Ë€£Íƒ­¿}ª–d]>`F6\,5\©³¾.J>@aj]€SIk;:`8;d;Al1=i0\#8e3]!6[,R1X*En1My+Jw=g7_ /W2Z /W .V1Y5_;l%B}4P‘5Q’4QŒ)K +4b0] +5_5VG`uL\f*;G'>L";H">JTs~jŠ•7bnUi H^)0B6:D-4')!$')&(*.k„‹©Ôì°Üô°Üõ©Øð Øí¢Öîl”³:Y'Dl=g%Ck6\$IIm Íë˜ÍëÈä—Ìè¦ÖñªÚòªÚñ¦ÖñœÌè”Åá‘Çå”Ìê˜ÐìšÑížÕòšÒðÈå‘Éã–Ïê“ÎéÌéŽËéŒÊé“Ñò“Îò’Ëí”Èè”ÅáÊã¤Ðè ÏéÌæšÈãžÌå¡Îç§Õí¬Ýô¬àöªÙï™ÀÖ?\s+@WGYo)I^'Lb:Q1((* C:hAu&V(Y“8CCcn]€‰,R]#La;]p%8F3T.F 6 (#/Hq—Bv¦C|"Y–6h¥(R;t0LƒYi£X^˜_`šdfbkžGb–Je•\eŽ^UxfRstY}™xŸ®€¨¶€¥¶{œ³{›¬‚¡˜~Ÿr\‡OBs¶·ÇAClZM{G>i#*O06\8=f:Eo!4]3\5^-S$5V0@a,?b)?c&=d1Y 'P'O(P 0X2Z 0Y8_>d8c:o(E1O‡7Uˆ>m1_3`2\2S;Sh+>M8O],FSA]iGdo%BO-GY%IW4=&1!  &1GXŠ­½™¿ÎªÚîÐìŒÃä»Ýy¹Û|·ÛM€¥-\€QrQoMi=X ,INr£Îé™Çê”ÄêÃ䆽܂¹Ûˆ¿á†¾à‚¹Û}¶Ùr°×uµÞ}½â€Àã~¾âw·Ýk­Ûf©às²äÄëËï¥Êë²Óï¯×òšÊ抿Þ{·Ûm®×b©×Y£ÕW£×]©Ûb«Ûh¬Úr³ÝzºáˆÆéÌé›Ðë¢ÌäUq†3DV:FW1E,B,C '=%7$-?T‘¸YžÏ#dOŽ1a Af¤6X’:p3Jƒ[f gk¥gj¢dm£C^š3o&5h@Bm[T}XNx`Kz‹`”™qœ—y˜‹smUty`†“u¢~g•ÇÄÔl_Ž…m£q`˜NOJHu>J7G*:Q06P'@,#I^k«Íj«×cŸÐ+b™P/^Ÿ2]™Dx7l@XŒ[m [i›[i›Qg£1K‰-c-\0:eVW‚G?jI6eUFqWOuFDg66Z88^FIwU]¾ÁÑKHw{l €i¤{f¥re¢\^“/Cq0X -R5[5EkWf7@g 1[.X°·Ä,;^R[„hjif¡hbŸ^d›Ld“(Jr3Y-T(2[&2]&6`&>e1V)K 2T7] -V-S1V +6[5]%Cn;g!Fs$Ew(F}4NŠ;P‘BW‘H`‹GcŽHg’Ro”I_{ANb?DT?AMIMQQVUX\]KNV)7"Sb2bm%8?%"&"  ;N[‡¥¹ˆ°Ç‚­Âx£ºx·ãjª×r²ák­Ýa§ÚWšÉ7d“(HwV~|˜@t 0].W*R.]ƒs¬Îl¨Ëk£ÊkžÈkžÉp¤Ît§Òy¬ÖŠ½â–Çä’Ä↹Ú~µ×z²×t®ÕoªÑr®Ôq®×n®Ùn±Ýo´âg®Þ\§ØRŸÐL—ÆQšÇU›ÆU™ÃZœÄp¬Òw²Úd¡ÎPÁQ“ËP’ÏJËDÅA’½P³4Rs0>W?VdES@S)BY&5N":0.K^»Ï‘ÁÚ†¹Ø³Ýe˜É"Q„>qGz7ke!7`%7b"5`&J4M\ 5C"%3g!Dl 3Z /V 2Y .V1Y6^4[7_4b;l3T„8X‡V‡JaŒF^,Im#El=b *I6L1BP28B65;IDGgcgRU]"/8 !'$*,24;@@HH7@:EY^…®Ä®Æb’«R”RxŠ†Àà‹Ãâ‹ÁáÂã†Ååe£Å!Lr3]X~ ‚žL1X/S+P;_S€¥]‹°Q‹·FŠ¼F‰»GŠ¼F‰»KŽÁX™Êc—¿a‘¸_‘º]’¼fžÉm¦ÐoªÕr¬ÙnªØc¢Ò`¢ÒZžÑN”Æ\šÅp¨Ìx¯Ñ{¯Ð³Ó„´Ñy¨Èq¡Äc•ºb–½n¤Ïi¢Ð_™ÉY–ÊQ•ËN˜ÆE~¤(?c4;WIYk"F\$Mh!D\4J 2D 0##@XlŸÃgªÙ`ªÙ^¥×a ÍMˆ·+dšK Q…?r6i Bu"Cq$Hs_&K Be™'W„8Z*I)I4U¦Â®Õï¯Øð¯Ùï¬×ì­Øí¯Ûð©Õë”Á݈¸ã„µåy­Þs©Ùi¡Õ\–ÏSÃL†·TÀ^œËa¢Ï\žÌ\ Î[ŸÏWœÎR•ÉJŒÀMÁMŒ¿H‡½?„Á6|»/x¶/{·)x±*{³8º=€¹9€¯?t›)?c07SAPc@Y&Uq Ke7L!5F-$:%Y‚#l¡j¦*|´K”ÃS”ÄF…º0k¡P†"P„Fz9l6c4^5]3Z2Z.X -Z#8g'BKYZcgchKQP!B<3+6,#.(;<;=ANDJ€Ž™’»Öp£ÃY‡¤Lr‡@ev[“¾\“¼_—¼b›¿n¤ËM{¥6` -V +PAb=g†,Pq0N/M .Q0[ƒT‹·S»U»Y’½^˜ÁcÄg¡Çf¡Ä[™¿V•¾Z˜Á[šÄY˜ÂX–Âc›Çz§ÒˆµÝ½à”Âã¥Óò¥Ôð“Àà~¬Óo¡Ëb™ÈPÂ9{³%l¨f¨i«gªl®sµ"v¸%r±2r¨J|©Jn)B\'=S6Ka$Faqˆ!‡¢6W&9,:9 .aw’¢Èìy«×s¬×t®×`ÊO“ÅJÆKÈRÆK}±;d“1Z‰?n 4`:c +6\.Q1S 7[Fk#Ho;b -U0Y /T-O¨µÁ4X:^">d7]&f9_!?d9] .T+U-X.Y 4`S0F](NiwŒ›:[&: *: <,$>\OwŸH|ªU¾V’¿J„¶D}·>~»8}º:¹D…·?y¥3b1\‡Hr9b4[ 8^ 4[1W 8_>f=f8b9c=e -SªµÃ;c+En*Ak5_6^:a0V-R +2V/S/T +1[ 0[ 0\8c>i 3^ +3^1[2\ 6`:d>h;e 1^"@kRiWkŽPeŠ:T~=g0W8^.RtVtgzŠDNT9:8MJF^\ZVSSZSTSHH1-*G\Yy…dgjGMK520"*Xr’s›Ã¦Ë‘±ÌºÒI´J‚²SŒºl¥ÐºÜP‚¢4V/R3U3RRpŽ1Tu7U +)G)L0]†p§Óu°Ýy²â}´ã€³ß†¶Ý€­ÒsžÀu¡Å}¨Ì~©Î«Ï†±Õƒ®Ò‚®Ñ†³Ô–Ãâ”À܉µÐ¹Ô½Ù‘¾Ü„³×t¥Ïp¢În¡Ëe™Äc˜ÄižÄo£Çr¦Îf›Å]’½R‡±K¬Hz¦Hp•@]y3J(>5MJd{x’Ce)>$5;9 %O%Z"dœbœd'cœ.`š'`œ^š]”)jšB§]ŽµY…«Iu›7c‹Bl 6a 5`6_4\0Z +2]8e6c2\ .V©¶Ä5^2]0\4`;e5^ 1Y.U3Y4Y5[ 3]6a 4_8c8c=hi•Ft 8f6a6`5a1]0]4c 8c2Z§·Å0Y.X3^8d4a0]2^2]5_ 7`9b7b8c:e>i9d 4_2\2Z2Z2Z3[5] +;cBj;a .R+O/W =k3g–_¼‰·â¸ßkŠ¦Qds[diGQW2vAy£I€®QˆºN…¹H‚µ@{¯4n£.hœ7p£;t¦9r£=v¤;t¡6o0i–:s K„²Oƒ°eµ[z™2H`%8+/6i}† (Mn7CY 3- (]v’‡¬Î}©Ìs¡Ál™»i™¿`“ÀU‹»lžÌ€¬Õ‡¯Ó}«Îq£Èi™Á]Œ·P}«Iu¦N{­2d’Cr :j +6g 4e.`2^8_¦·Å/X/X2\ 1\3a8g:h7e9g@m7c 2] 6a 5` 4_ +3^.Y-V1X3[1Y0W/W1X0U1TBc,Y{@ušZ4VuHh€ZtˆYŽ¾T¹J‡´E‚¯Q‚±Jv¡>c+M)N)U_‘¾Kƒ®%^‚ GP%/:*0:V]kd–¬Q|‡CQN'16$ ",?TjX|›e‹ªnªn¡ÍiŸÈb›Æ`šÇh—Æ[‡±Be,M*OFq@o¢5l¡,e’Di-N-Q O"6'+#?\z¦Í±Þz¬Ún ÏW‰ºEw©>p¡8jœ>p¡?q£BxªF°D|­K‚²Nƒ³U‰¹]‘¾g™Âo¡Ét¥Îp¢Êe–¿\¶Tˆ´H¯·ÊÛT„SƒT„U… U„SM|JyHvFtCp?j +;f5`6a :eHs.Z…Sz¥j’½m•À`ˆ³T|§Pz¥Bv£,e”JzCtL}L~Am +Io\‡$[~CarZgnYgqTal?JT",6'1;[enr{…Zhp.Wcd\n0GINVdlr‚yx~gjpGTc5Qg@X/DbÁj–Çw¢Ò}§×|¢Ôi»Dj*M*P0TdÀ>o¦*[‘'V‰An:^.M@d5h’;m˜Lª]ºb•Àa’¾[ˆµY†´X‰¸K€¶/h¡TMˆO…Q‡Q‡SŠ#Y)_•(`—*b˜5gšGs¡\ƒ«hŠ®y˜ºƒ¢Ãˆ§Èƒ¢Ãx—¸p²s’µp–¸i—µUy”$;T%>6467[#Q~'Ko4G[5DU':!&-H0X}9g‘ApšQ~©Y…²T€­Bm›2^‹2]‹Gs bº^·T„®T…±[º`“Á]½X‰³S„®O€©Hy¢:l•=n˜ošKy£b¸t¡Ës ÉZ‡°DqšEsF}©7t  ]ŠX†Xˆ K{FrY€W€DaJ_kt}cpz7ER(2-8BT^guˆcmv/>F 9FqD‰›s‰Œv}‹djzHIM&,/ , &:4H7c•p›7k“1h-eŠ/f‹4j7m“ByžF~£7o–+eŒ%^‡ Fo@jQz"W€Ai C_oyƒ‡‡ŒLS`(4+5?U_hfpyV_h4=F*1,]hV©Äl«½t…ˆOT^!)2  &=NZdy‰~“¤§Õ„¨Ø‚£Ô‚¡Ó„¤Ôs”Á?h +R ,V8[Šl•¿a“·W‡´Al¢)Pˆ8i +-V9gK€-\‘Hw¬N~³Ix®Bs¨&b•PM|HuMx+^‡R§wœÄ}¡É}¢Ê£Ë{ŸÇ{ Ç…¦ËŒ«Î¯Ó’³Ø–¸Þ–¹ß™½äžÃé Äê Äê Åë–»ás˜½_†®X€ªPt›%Bb 6(&'0"8MgŽk“ÃušÃSj…-?S'9((0Jv™½Š³ÜŽ¹ä¹äµßŽ³Ý‘·áµÞµß“¹â”¹Ý‚¨ËgµS§;i“)Z…%W†OƒN„N„O…!Rˆ$TŠ-Y†0W|¹ÇÓPt˜dˆ«p“µ|žÀ‹©È•±Ï•²ÐŠ§Å‚Ÿ½x•²fˆ©Drš3b‹$S}Al9d:f;cc;`<`=a =aDi @e;`In)^…"U}+ZOk†‚ˆ’ols.1>*2>HQYS[c8AH!+3'2;AR[b“¡j½ÔSŠ™BJO %"&%DJK`hm‹˜¢¯ÀΪ½Ë‘±Õ­Ñ}œÀy˜¼z˜½a€§:d -Y /^(Rƒ6f–)^Œ)[Ž1]’5[Œ?f6T=dGyK~Q„-_‘8jœGy«N³Dx©;n 4g˜-`‘(Z‹%Wˆ$U†!RƒOM~IzDuKz+X†5b9f•;i—Ft¢e‘¿„®Ö¶Ü¸ß‰³Ù„®Ôx¢Èm˜¾l—»g®3Qm "8 '- :#Fn%U…%XŠ%Nz*Dc#0C!-& ;BbˆRy¦MwªBmž?j—7b;f’?j–2]Š.Y†.\ˆ%V#T%W‚$V‚'Y…)[‰!T…N€N€M"U‡([Bm™Z}¢ÍØå}š»Ž§ÅŸ¶Ï¥¹Ñ¦»Ö®ÃÝ·Ìä³Èß®ÃÛ£¸Ò“®Êt½Bn‘Ag8`;e;hi”;f’Cn™7b.Y…'R}&Q}2]ˆ8c.Y…$P{$O{"Mx Hs"Hq(Ox0V4Zƒ3Y‚)Ox-U|.V}-U|)Qx*Ry)Qx#Lr$Mr/Tu'D` +5& +#)D-Qx&S#U†#Nz5St1D[+:&3:[JsL| O€$O|"M{#N{'RIvIvMy Pz Oz Pz$T~)Xƒ'W‚IwGv$S‚,[‹.]Œ)Yˆ([Œ&[Ž²ÄÖ"Rƒ0]Œ8cDm–Oo”Hf‰A_‚Db„>\~2Ps*LnEf =_7[9_;a;c:b:a:a:a:a:a:a;a Ag:_8\KnIl5X =a/WsKdvP^kKS]RXb\ck/5; +BOZj^|‘:~’ hw L\?LZkmr“™ž‡Š‘uyyX]`8?EEQ[8HS‰­Ó´Ú•¹ß–¹ßž¸Üs‹®!9\-Ph‚¦©Î‰¦Ê³Ô€£ÉnŒ·rŽ¶`zš8P-KiiŒ±jŒ²mµr•ºmµhŠ°eˆ­g‰¯gŠ¯d†¬c†«iŒ±t–¼} Åƒ¦Ë…§Í…¨Í…¨Í‡©Î‹¬ÏŒ«Î¬Ï‘°Ó“²Õ‘°Ò‚£Æv›ÁxžÆvœÃfŒ³Tz¡Pu[€§iŽ´kŒ¯1Mj1&4LeŠ¬Ñˆ±Ü®ÛrœÆVxœ)Fc2E,,&A +8\:g >nCp!LyHuFsHuHuKuJsEnDmGpKt%R{ JuBm=g>h@jIs"O}Iz®¿ÐL}M|DsDsJu IsEp8c 5` +3^2[4X8[8[8\9^8]7]5\4\5\4\6]6^ 9` +;`2W@cHk5W1T#Np4Vp6L]O\ggpwaip@EM :BKp€Žkƒ˜5TlK^cs@‚’qŒ˜’•“–žipv388 &.2?I=dŒBi‘LršW}¥mµSp— (N1Lp˜²Ô§¿á¥Ààž¿Þ–¸ÝŠªÔˆ§Ðy—º#A^/Nnm³a‚§Jk9[6X|8Y}?a…Pr–\}¡h‰­p’¶{œÁ’´Ø™ºßš¼à™ºß’´Ø“´Ù–¸Ü›»Ýž¼Ýž¼Ýž¼Ý—µÖŒªË‰§Êƒ¤Ë¡ÊŠ¬Õ“µÝ–¸á™»ã˜¹â—¶ß”²ÖId4'"%?X`€¥`„«Qx¡9`Š)Ow%Lp=W/+29Z@m6g2_1^2_ +5b 8e7dCl"Nt&Qx!Ms Kr#Ou+Tz9]ƒDhŽLp–X|¢a…«kµt”·q®ËÕápŽ°o³Qq–3V|,V‚,X‡+W…$P&R€Cr=k >g:a:`:_7[ >a@eBiKq)U|,XEk 6]:`2W;^/Wz6]-RtIp’gŒ­]y“N`pkvy‚†NV[!$)==B`dm†“¢u‹¡Hh€CsƒY‘¤z³Ã…¨²ˆc`i,49 +  ?EJ`lt2[…:dŽ=f‘9cU~¬Ah–*W;\…mŒ³x”¹u“¶W}ž9^‡&K{%Jz Gq>b4Y>f!Fn*Ow.S{,Qy(MuDlAj&Kt0U}1V~6[ƒ>cŒEj’Y§b‡¯k¸l‘¹gŒ´iŒ²g‰­_¥TušDeŠ?a…Tušhˆ±~žÈ‚¢Ëy™Â†¦Ï­Öˆ¦Ð‘­Ö™´ÙOi†1%"'C\]|žDd‰9[‚.S|=j:f@b8, .?1`2d3` +5b:h!Mz,X…9c^‡®q™¾f³QzžR{ o—¼…«Ï“´×›ºÜ¼ß¡Àã¤Ãæ¢Á䡽ܤ¼ÚÖßêqŽ¯\|¡BeŒ/T}$Ny(T€&R~$O{%P}%P}"O|JyFsJu!Iq&KqEiSxœW~£b‰®n•»sšÀ`‡­]‚§^ƒ§Z¢i¯f‰ª@aƒFg‡kŒ­r‘²k„›pŽƒ”jsv)34" E;;e]_][ackw^p…\u‹‡ ®µÉ”¾ÎmŽ•KDL8/5'(!%&?@>hihˆ‹Ž ©²z¡ÌeŽ¸S}§Ku Fs¡Gu4`Uw¡jˆ°f€¦a|ŸUu˜Gh7\Š+U…(Uƒ"R}=f#LuIqšPv Z|¨e…±d„°Uz¤3Z„-T~*Q{'Nx8_ˆMtRw Uz£Rw¡Z©_…®W|¦Vz£SvPs›TwžZ}¥Twže‡¯ È‘¯×”²Ú’±Ù’°ØŒ«ÓŠ¦Î¨Ï‡¡ÅB[z3&%4QEgAc‰0T{Cm8e 9gAh*J&@*C;1Z?lBnAlEqFp"Is"Is&Nv.V}0X€,T|BjBj$Kr*Os/Sw0Sw4V{<\Ba‡AbˆDf¸ÅÓ#JtFr LzKzDp?k=hAmDpBmCpHyJzJy$Ky*My)Ku'Js$Jr#Iq#Iq#Iq'Lt5Z€6Z=_‚Eg‹6Wy+KlDd…Ji‰1Pq-C_jvˆŽ–›OXX!511dWUc[Z77;JS_dt‡…˜­¬»Ë§²Ål„’j?gCj&Py,R|3W6W‚3Y„3]ˆ.XƒGr?jCmFpBg7\€7Z>`'IjLmŽ;^|"CcCX{„¨zƒ†4><)1fae{pm@>> Q`k•¦¸ÀÒæÀÓ暨·DKS!%""%RSW„…‡¥¤¦¥¥©˜—š„‚‚x{q”¼Nt›*Qx 7]-R/S+NHo‘†©Ê‚ À}™¸mˆ§Ut”@eˆ$RxPy'a‹Ou3V/S6]>f"@j">i$Fo"EmAi;c8`9a7a 2_ 1^5bDq7]ŠRw¤g‰´o¸v–¿zšÃy™Âs“¼d„­YzžTv™WyœYzTu˜Vwšb€¢u®uŒªAUp30-*G>[|If‡If‡EbƒDa‚MiˆNc8Mi2N,I >/N9[€-Y„ LxJvDpIv%O|$Iq'Hm)Jp*Kp)Jp:[€/QvDh$Im)Lq)Jo-Kr*Fm AiBk¬ºÉDmEn Hq'Nw.S})Lv%Hr*Mx,Oz=`‹d…ª›µŽ¦¾²Ë§¹Ô«ºÕš©Åv‘´V}¦?g(OxFo Hp>fDK?@Cbac’‘’°®¯°®±‹Œ‘a`cBAA(*->aŠBi7]:`4\0X4Z<_Df"IiDd!Cd!EgBeBfMsKqFk ?bAf@e>d@g#Go+Nv+NvBj8`5]4\7a5b5c;iBpEtEsBm(HqAaŠ_¨jŠ³Zz¤@a‰Bb‡Op“Yzh‰­yš½ Ä ÂªÉŽ£½KYn"-@2 12E]›®Ç¬¿Ø¯ÂÛ®ÁÛ¬¿Ø®¿ØµÄÙ{‰Ÿ->U(A 92NsŠ¥yªp‡¤F_}%@_(Ef1Nq/Kk5On3Nm-Hg+Fd0Kj/Ji.Ih1Lk5Onc`=_2Orh¤u±\wš?_€'KkDc=^=`±½É'Gk.Or1Qu)Jm"EhBd;]2T7Y<^=`FkIo#Jq/S{5V€2Pz2Qw+Kn!Ad&Fi,Ko&Fh,Lm,Os:]3V/Oq&Gh +)I%F^Il€5Uu.LCTa„‡mci3&* + 58^…<^„<^…3N{2a7dYu qŽ¸u“»‚ơΡΑªÔ‡¤Ì_€¥Jk*Ho)RNi’’­×ªÔ’ªÔŽ§Ñ„¡ÉžÆ ÈÅd‚ª:X€0KqXw.Hg'Ba(Cb7RqM*Fe%De?b Bg@h En>c4V9[>`%Fi*Ln#Cf(Dh3Os7Ux5Ux&IkAb=`3W¯¹Ç+Hm-Ko-Jn/Mq.Nq&Gj%Fi?b?b#Dg Bd8X;[;\"Ce-Ln2Ps2Ps5Ux,Ko)Il(Gk<^'Eh-Mo>`+Kl9Xy7W (H0Kfe*Fm">e5\7^">e&Dj>b5Y4Y9]>bCg Ch!Agb'Ba6Ic&3G."4I(If)Hf"?^%?`*Bd,Df!?_#Ed Aa;[!Cb"Cb1Rq*Gg4T2R1R.N +'H +'I 'Lª´Á,Q,Q5Z8]9^'Ch">c;`(Di.Ko-Jn/Lp0Lq*Fk*Fk)Fj+Gl/Mq&Gk@c"Cf @c @a7Vw-Kk<[6Rq4Pm#>\A\xZsŽ1Hc)C4Leavˆ[it$)!TPRrt|Wan'6F,=N]mœ®´ÃÔ¨¶ÄwƒŽGQ[+5=-25^__€„†§ª¬ºº»ÆÇɵ۞¶ÜŸ·Ýž·ÝŸºß^zŸ,Q9_A]‚B^ƒA[€a2Jm7Nq%>a6Y9Qtl„§š²Õœ´×Ÿ¶Ø¢¶×¡µÕŸ´Ôž³Óž³Ó±Òœ®Ì•¥Âº„”°v†¢q‚žn€VnŒ6Pn,Ec)B`(A_)B`,C^0@W8BT'-:$2'9.?W,Ec&Cd%Bc+Gh$Ab;\<] ?b$Bc&?]&:T(7M 4 1F1Jb;UoAZw]?^;[8X5U8X9Y;[;[ *J A$E©³¾ )J-O;\-Jk/Lm&Cd*Gh*Gh0Mn.Kl">_*Be2Km:SuTo:Ng6Ia6Ib2E`*=['9Y&9Y 8V8V7U(A_(A_'@^CXuHWrBPe,:"18F[IXs4Ig+Dc$>\6U 9X 9X#=\,Gf6Pn7Ok;Pj.@X%<>Oc]p‚Ocy>Tn0Gf*Ce8];]"Dc-Nm(Ih"Dc@_%Ed'Ee5U7W<\0P &F-K1N¬¶Á8U%B`(Fc&Da*Ge*He&Da;X#A^'Db;X2O+H6S\0O!3S):Z"6U5R">Z)Je%F`%@\+Eb#]&Cc8X0P-M &F4T"@]#A]³¾È$B^=Y#>"< +D +*C 88O;R"97LE_t2Lc+E6Ni_wTi{2@L-4:YZZjll:BH ',:Vkz‰œª ¬Zju"0; " )5U]iŒ•ª¶¼¼ËÔ³¿ÆŒ‘’iji–¯Ô–®Ó”¬Ñ¨ÍŽ¨ÊoŠ«!<]8Y#>^)De!=\8U6S7U!9X'=]'<\&?]:W8T:V$B^#C_5R0O4T4T.N.O":[":Y6R,D_6Ni4Lg2Jf-E`3Id,B\5KfCYvI^~Sh‰Pf‡HcNj‡Fa~,Ea!9S#:T+A\&=X*B[ #91I8Pl2Ih5Ml7Pn+Ca&>\";Y/Hf5Pm4Sl@YpQcyXhI_z%Dc0HP%:P)@\&>_5W@^B](Kg(If'Ec#?] 9Y3Gi7Km(?`6V.M *I +'C )C«µ¾-F +D'?$; 9 ";'B(D 'D +%C (E +(C +)D ,F (C+F-H +)E -K ,J&D%B-J-H4L:Sj=Vn&AY=YsUrŒ6Pi!7NI^tbuˆP_n6@J>DJaacaac&,1+Z!;X"8V/Cb2Dd/Fe)Ec!=[ =[ =[$C`"@^9[4X$=`7[!9].Gk,Ef%>\8V!;Y6T6T*Ca5Ml)?_+Bb1Hh.Ee6V1P7V A_#A^">Y+D](@X(@W-G]9Q8 #=4N5P9V8W-L2Q7V'@_%B`A[,H_;Lb5F\3Pk5d„7Q 9K4Nb1Lb8Tn3Ol%A`C^=W8S6R0M&E"B#E'H'H(H 'E%B&A/H¬·À0I1K6P7P$:R';R#9R8R6R,K,K3R3R0P!6U0O.M %E )K$F 'I,M8X-K':P@Pf4G^%:S>VoGa|5N5JYljyˆOZf^!:Y+Db/Hg.Ge2Ki5Nm3Lg4KbEe?Fi8Ce*<\.L &B +)E +$D !B &G.O2S#;\(Aa3Lj,Ec&@^8V3Q1P*G,H4P XpD]wAYu0Id!9U4P$3AVhs†VbvANc\jWf|&8M1EK]oZixEP\FMVV[cgimLMP #)~ˆ¨¬²¥©¯qw}>CI049Y]a—šžÒÔ×ìíðÝÞá—š^bf:>A%>\2P0N0N4R4S+I,J#Vq=Rf>Qe>Nc?Kb@JaMVm\\z]Z}TWwBLj.B]6N0H &B 'E0N,Ec=Vt +'C'E'E3Q'?^3Lj1Ki&?\,D^-F_":S'A%?&@ 71¦­µ#=8;XIEd4.M*?+< $7 5!8#; &A'E&E#B(G/O'F)H +"A*I-L4S'>[+G$/FV_tV_sW`sx€“pvˆ>K^8MbK]oIWh@KXJQZbgodhl>@C +,,3µ´¹çåæ×ÕÒ–”’a_^XVU|zy·¶µáßÞìëêÐÏБ“LOR),/  \ No newline at end of file diff --git a/examples/art/line_patterns.bmp.zip b/examples/art/line_patterns.bmp.zip new file mode 100644 index 0000000000000000000000000000000000000000..0f6f70b778273e2f7267f9f557c7dcbc01b7214d GIT binary patch literal 8548 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 literal 0 HcmV?d00001 diff --git a/examples/art/line_patterns.tar.gz b/examples/art/line_patterns.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a6a2c99a58584749938fc56844bd781c24a37f4d GIT binary patch literal 6276 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 literal 0 HcmV?d00001 diff --git a/examples/art/shapes.txt b/examples/art/shapes.txt new file mode 100644 index 0000000..5bdba8a --- /dev/null +++ b/examples/art/shapes.txt @@ -0,0 +1,10740 @@ +=======BeginShape +Path -1 -1 0 607 -1043 +Curve 704 -1101 804 -1117 +Curve 896 -1122 988 -1126 +Curve 1073 -1120 1157 -1094 +Curve 1240 -1069 1316 -1001 +<-------EndPath +Path -1 -1 0 550 -1069 +Curve 554 -1074 557 -1078 +Curve 606 -1135 684 -1187 +Curve 761 -1240 877 -1255 +Curve 962 -1265 1046 -1275 +Curve 1099 -1279 1195 -1256 +Curve 1291 -1234 1396 -1135 +<-------EndPath +Path -1 -1 0 463 -1101 +Curve 512 -1225 577 -1297 +Curve 642 -1369 725 -1416 +Curve 807 -1464 911 -1475 +Curve 1000 -1481 1088 -1486 +Curve 1161 -1487 1219 -1454 +<-------EndPath +Path 1 -1 0 510 -1085 +Curve 487 -1093 463 -1101 +Curve 396 -1119 328 -1136 +Curve 202 -1161 62 -1165 +Curve -73 -1169 -215 -1136 +Curve -246 -1129 -277 -1121 +Curve -311 -1112 -345 -1102 +Curve -372 -1094 -399 -1085 +Curve -439 -1072 -479 -1058 +Curve -546 -1032 -592 -995 +<-------EndPath +Path 1 0 0 -592 -995 +Curve -633 -963 -656 -923 +<-------EndPath +Path 1 -1 0 -656 -923 +Curve -659 -918 -661 -912 +Curve -709 -819 -660 -751 +Curve -612 -684 -466 -628 +Curve -320 -572 -222 -538 +Curve -125 -505 -101 -476 +Curve -93 -465 -92 -457 +<-------EndPath +Path 1 1 0 -92 -457 +Curve -72 -411 -73 -367 +<-------EndPath +Path 1 -1 -1 -73 -367 +Curve -73 -366 -73 -364 +Curve -73 -365 -72 -365 +<-------EndPath +Path 1 -1 0 -72 -365 +Curve -88 -319 -131 -281 +Curve -132 -281 -132 -280 +<-------EndPath +Path 1 2 0 -132 -280 +Curve -126 -263 -120 -246 +Curve -90 -163 -5 -162 +Curve 34 -162 60 -174 +Curve 96 -192 107 -236 +<-------EndPath +Path 1 0 -1 107 -236 +Curve 90 -259 72 -281 +Curve 54 -303 36 -325 +Curve 15 -347 -6 -369 +Curve -40 -400 13 -434 +Curve 71 -471 132 -482 +Curve 136 -483 140 -483 +Curve 166 -488 192 -493 +Curve 192 -492 192 -491 +<-------EndPath +Path 1 -1 0 192 -491 +Curve 242 -501 291 -510 +<-------EndPath +Path 1 0 -1 291 -510 +Curve 290 -514 288 -518 +Curve 358 -538 428 -558 +Curve 499 -577 594 -610 +Curve 689 -644 748 -710 +Curve 807 -777 771 -861 +Curve 734 -945 649 -993 +Curve 564 -1041 510 -1085 +<-------EndPath +Path -1 0 0 510 -1085 +Curve 530 -1077 550 -1069 +Curve 551 -1068 552 -1067 +Curve 568 -1061 583 -1054 +Curve 595 -1049 607 -1043 +Curve 717 -991 774 -932 +Curve 792 -914 809 -895 +Curve 817 -886 824 -877 +Curve 848 -898 886 -885 +Curve 914 -853 866 -808 +Curve 899 -708 769 -632 +Curve 662 -571 530 -549 +Curve 411 -530 291 -510 +<-------EndPath +Path -1 0 0 192 -491 +Curve 163 -484 133 -476 +Curve 55 -450 41 -368 +Curve 46 -355 57 -343 +Curve 67 -334 77 -325 +<-------EndPath +Path -1 1 -1 77 -325 +Curve 88 -318 99 -311 +Curve 106 -301 112 -291 +<-------EndPath +Path -1 2 0 112 -291 +Curve 113 -291 113 -291 +Curve 148 -254 182 -216 +Curve 186 -211 190 -206 +<-------EndPath +Path -1 0 0 190 -206 +Curve 211 -172 232 -138 +Curve 237 -128 242 -117 +Curve 243 -116 243 -115 +<-------EndPath +Path -1 -1 0 243 -115 +Curve 290 -106 337 -96 +Curve 391 -81 439 -52 +Curve 489 -22 521 28 +Curve 554 83 519 135 +Curve 498 162 466 179 +Curve 416 204 363 221 +Curve 309 239 260 260 +<-------EndPath +Path -1 0 0 260 260 +Curve 258 272 255 283 +<-------EndPath +Path -1 -1 0 255 283 +Curve 301 307 357 282 +Curve 371 275 384 268 +<-------EndPath +Path 1 0 0 77 -325 +Curve 95 -308 112 -291 +<-------EndPath +Path 2 0 0 112 -291 +Curve 113 -260 107 -236 +<-------EndPath +Path 1 2 0 161 -167 +Curve 132 -116 147 -63 +Curve 152 -42 165 -20 +Curve 185 13 232 8 +<-------EndPath +Path 1 0 -1 232 8 +Curve 224 -28 216 -63 +Curve 215 -66 214 -69 +Curve 206 -89 198 -108 +Curve 180 -138 161 -167 +<-------EndPath +Path 2 0 0 161 -167 +Curve 172 -187 190 -206 +<-------EndPath +Path 0 0 0 243 -115 +Curve 241 -116 238 -116 +Curve 235 -115 231 -114 +Curve 215 -111 198 -108 +<-------EndPath +Path 0 0 0 238 -116 +Curve 240 -117 242 -117 +<-------EndPath +Path -1 2 -1 278 -6 +Curve 278 -6 278 -5 +<-------EndPath +Path -1 2 0 278 -5 +Curve 280 73 282 151 +<-------EndPath +Path -1 2 -1 282 151 +Curve 282 151 281 151 +<-------EndPath +Path -1 0 0 281 151 +Curve 266 209 263 255 +<-------EndPath +Path -1 0 -1 263 255 +Curve 262 254 261 253 +<-------EndPath +Path -1 0 0 261 253 +Curve 261 257 260 260 +<-------EndPath +Path 0 0 0 260 260 +Curve 258 261 256 261 +Curve 224 273 251 295 +<-------EndPath +Path 0 -1 0 251 295 +Curve 253 289 255 283 +<-------EndPath +Path 0 -1 0 278 -6 +Curve 271 -35 263 -63 +Curve 253 -89 243 -115 +<-------EndPath +Path 0 0 0 866 -808 +Curve 860 -822 854 -835 +Curve 839 -856 824 -877 +<-------EndPath +Path 0 1 -1 228 172 +Curve 222 195 215 217 +Curve 190 288 134 321 +Curve 80 353 2 363 +Curve 2 366 2 369 +<-------EndPath +Path 0 3 0 2 369 +Curve 33 370 63 370 +Curve 177 374 243 312 +<-------EndPath +Path 0 -1 0 243 312 +Curve 246 307 248 301 +Curve 250 298 251 295 +<-------EndPath +Path -1 -1 0 251 295 +Curve 253 296 254 297 +Curve 255 298 256 299 +Curve 300 330 357 328 +Curve 369 324 381 320 +<-------EndPath +Path 0 2 0 281 151 +Curve 270 156 259 160 +Curve 244 166 228 172 +<-------EndPath +Path 1 2 0 228 172 +Curve 169 192 110 212 +Curve 13 238 -89 244 +Curve -90 244 -90 244 +Curve -186 229 -245 193 +Curve -260 183 -274 172 +<-------EndPath +Path 1 -1 0 -274 172 +Curve -275 172 -275 171 +<-------EndPath +Path 1 2 0 -275 171 +Curve -361 157 -409 117 +<-------EndPath +Path 1 0 -1 -409 117 +Curve -412 117 -414 116 +<-------EndPath +Path 1 -1 0 -414 116 +Curve -432 196 -421 293 +Curve -421 295 -421 297 +<-------EndPath +Path 1 3 0 -421 297 +Curve -421 303 -420 309 +<-------EndPath +Path 1 3 -1 -420 309 +Curve -417 309 -413 309 +<-------EndPath +Path 1 3 0 -413 309 +Curve -399 335 -362 351 +Curve -267 390 -153 377 +Curve -133 375 -112 373 +Curve -94 372 -76 371 +Curve -37 370 2 369 +<-------EndPath +Path 2 2 0 65 118 +Curve 131 107 164 66 +<-------EndPath +Path 3 1 -1 170 282 +Curve 173 280 176 278 +Curve 175 279 173 280 +Curve 172 281 170 282 +<-------EndPath +Path 3 0 0 33 483 +Curve 70 475 106 466 +Curve 116 458 127 453 +<-------EndPath +Path 3 -1 0 127 453 +Curve 129 452 131 451 +<-------EndPath +Path 3 4 0 131 451 +Curve 134 450 137 448 +Curve 139 448 140 447 +Curve 176 435 210 456 +Curve 224 469 237 481 +<-------EndPath +Path 3 3 0 237 481 +Curve 238 481 238 481 +<-------EndPath +Path 3 -1 0 238 481 +Curve 222 366 243 312 +<-------EndPath +Path 0 3 0 33 483 +Curve 28 484 22 485 +<-------EndPath +Path 0 4 0 22 485 +Curve 24 508 26 530 +Curve 26 536 26 542 +<-------EndPath +Path 0 -1 0 26 542 +Curve 29 608 14 748 +Curve -1 889 -29 943 +Curve -58 992 -87 1040 +Curve -117 1083 -148 1250 +Curve -153 1278 -158 1305 +<-------EndPath +Path 0 -1 -1 -158 1305 +Curve -155 1306 -152 1306 +<-------EndPath +Path 0 -1 0 -152 1306 +Curve -103 1232 -61 1154 +Curve -20 1076 14 992 +Curve 48 908 72 814 +Curve 95 722 108 628 +Curve 121 547 134 466 +<-------EndPath +Path 0 -1 -1 134 466 +Curve 131 460 127 453 +<-------EndPath +Path 4 -1 0 131 451 +Curve 132 453 133 455 +Curve 134 458 135 460 +<-------EndPath +Path 4 4 0 135 460 +Curve 136 454 137 448 +<-------EndPath +Path -1 4 0 134 466 +Curve 135 463 135 460 +<-------EndPath +Path 4 4 0 135 460 +Curve 140 471 144 482 +Curve 173 468 210 456 +<-------EndPath +Path -1 -1 0 133 455 +Curve 134 461 134 466 +<-------EndPath +Path 4 -1 0 134 466 +Curve 136 486 138 505 +Curve 186 483 237 481 +<-------EndPath +Path 3 -1 0 237 481 +Curve 238 482 238 483 +Curve 238 482 238 481 +<-------EndPath +Path -1 -1 0 330 358 +Curve 261 360 256 299 +<-------EndPath +Path 4 -1 0 -172 1377 +Curve -171 1377 -170 1377 +Curve -127 1378 -83 1379 +Curve 4 1375 90 1371 +Curve 124 1365 196 1371 +Curve 30 1288 -67 1335 +Curve -114 1358 -165 1368 +Curve -167 1369 -169 1369 +Curve -170 1369 -170 1369 +<-------EndPath +Path 4 4 0 -170 1369 +Curve -171 1373 -172 1377 +<-------EndPath +Path -1 4 0 -172 1377 +Curve -173 1377 -174 1376 +Curve -175 1376 -176 1375 +<-------EndPath +Path -1 4 -1 -176 1375 +Curve -177 1375 -178 1374 +Curve -179 1374 -179 1374 +Curve -178 1373 -176 1372 +Curve -174 1371 -172 1370 +<-------EndPath +Path -1 -1 0 -172 1370 +Curve -171 1365 -169 1359 +Curve -168 1352 -166 1345 +Curve -162 1325 -158 1305 +<-------EndPath +Path 0 2 0 232 8 +Curve 255 1 278 -6 +<-------EndPath +Path -1 -1 0 -345 -1102 +Curve -382 -1205 -478 -1264 +Curve -574 -1324 -699 -1305 +Curve -825 -1287 -869 -1257 +Curve -905 -1235 -941 -1213 +Curve -969 -1200 -1030 -1139 +<-------EndPath +Path -1 -1 0 -399 -1085 +Curve -439 -1186 -567 -1186 +Curve -695 -1186 -765 -1167 +Curve -836 -1148 -860 -1130 +Curve -889 -1114 -918 -1098 +Curve -952 -1085 -1029 -1002 +<-------EndPath +Path -1 -1 0 -277 -1121 +Curve -298 -1204 -319 -1286 +Curve -347 -1396 -428 -1464 +Curve -510 -1533 -640 -1525 +Curve -771 -1518 -834 -1495 +Curve -897 -1472 -977 -1419 +<-------EndPath +Path -1 -1 0 -319 -120 +Curve -379 -125 -438 -129 +Curve -516 -127 -589 -104 +Curve -666 -81 -712 -17 +Curve -764 55 -701 120 +Curve -650 174 -581 200 +Curve -513 225 -444 233 +Curve -442 264 -471 274 +Curve -506 289 -540 304 +<-------EndPath +Path 1 -1 -1 -92 -455 +Curve -75 -409 -73 -367 +<-------EndPath +Path 1 -1 0 -92 -457 +Curve -92 -456 -92 -455 +<-------EndPath +Path 2 1 0 -239 -202 +Curve -222 -190 -204 -177 +Curve -165 -137 -187 -63 +Curve -192 -48 -197 -33 +Curve -232 47 -304 47 +Curve -326 44 -348 40 +Curve -380 31 -382 -8 +<-------EndPath +Path 2 2 0 -382 -8 +Curve -383 -7 -383 -6 +<-------EndPath +Path 2 -1 0 -383 -6 +Curve -404 44 -409 98 +Curve -410 107 -411 115 +Curve -410 116 -409 117 +<-------EndPath +Path 0 -1 -1 -409 117 +Curve -412 117 -414 116 +<-------EndPath +Path -1 1 0 -319 -120 +Curve -296 -146 -273 -171 +Curve -256 -187 -239 -202 +<-------EndPath +Path -1 2 0 -239 -202 +Curve -184 -250 -132 -280 +<-------EndPath +Path -1 1 0 -382 -10 +Curve -381 -12 -380 -13 +Curve -368 -38 -356 -63 +Curve -341 -88 -325 -112 +Curve -322 -116 -319 -120 +<-------EndPath +Path 1 1 0 -319 -120 +Curve -302 -117 -285 -113 +<-------EndPath +Path 2 1 0 -382 -8 +Curve -382 -9 -382 -10 +<-------EndPath +Path 2 -1 0 -382 -10 +Curve -383 -8 -383 -6 +<-------EndPath +Path 0 -1 0 -592 -995 +Curve -757 -1026 -656 -923 +<-------EndPath +Path 2 -1 -1 -275 171 +Curve -275 172 -274 172 +<-------EndPath +Path 4 4 0 -288 493 +Curve -288 483 -288 472 +<-------EndPath +Path 4 3 0 -288 472 +Curve -289 472 -290 471 +Curve -325 467 -360 463 +Curve -417 465 -455 505 +<-------EndPath +Path 4 -1 0 -455 505 +Curve -458 519 -461 533 +Curve -376 496 -297 520 +Curve -293 507 -288 493 +<-------EndPath +Path 4 0 0 -288 493 +Curve -284 484 -280 474 +<-------EndPath +Path 4 3 0 -280 474 +Curve -284 473 -288 472 +<-------EndPath +Path 0 3 0 -192 519 +Curve -220 511 -239 489 +Curve -254 483 -269 477 +Curve -275 476 -280 474 +<-------EndPath +Path 3 4 0 -189 520 +Curve -148 530 -89 511 +Curve -56 503 -22 494 +Curve -12 492 -1 490 +Curve 11 488 22 485 +<-------EndPath +Path 1 1 0 -58 306 +Curve -75 336 -41 312 +<-------EndPath +Path 2 2 0 -212 77 +Curve -182 142 -124 143 +<-------EndPath +Path -1 -1 0 -409 98 +Curve -411 107 -413 115 +Curve -414 116 -414 116 +<-------EndPath +Path -1 -1 0 -472 345 +Curve -439 307 -440 254 +Curve -474 285 -505 334 +<-------EndPath +Path 3 -1 0 -192 519 +Curve -191 520 -189 520 +<-------EndPath +Path 4 -1 0 -189 520 +Curve -191 524 -192 528 +<-------EndPath +Path 4 0 0 -192 528 +Curve -193 541 -194 553 +<-------EndPath +Path 4 4 0 -194 553 +Curve -92 537 -89 511 +<-------EndPath +Path 4 4 0 -195 556 +Curve -195 555 -194 553 +<-------EndPath +Path 4 0 -1 -194 553 +Curve -199 554 -204 554 +Curve -204 555 -204 556 +Curve -200 556 -195 556 +<-------EndPath +Path 4 -1 0 -195 556 +Curve -85 549 26 542 +<-------EndPath +Path 0 -1 0 -192 528 +Curve -192 524 -192 519 +<-------EndPath +Path 0 -1 0 -288 493 +Curve -287 575 -278 657 +Curve -267 750 -268 843 +Curve -268 937 -283 1029 +Curve -299 1125 -314 1221 +Curve -326 1303 -354 1351 +<-------EndPath +Path 0 4 0 -354 1351 +Curve -353 1352 -352 1352 +Curve -351 1353 -349 1353 +<-------EndPath +Path 0 -1 0 -349 1353 +Curve -321 1311 -288 1240 +Curve -256 1169 -236 1075 +Curve -217 981 -224 897 +Curve -231 812 -214 725 +Curve -197 637 -195 556 +<-------EndPath +Path 3 -1 0 -421 297 +Curve -424 373 -455 505 +<-------EndPath +Path -1 4 0 -342 1354 +Curve -334 1367 -344 1372 +Curve -375 1379 -406 1385 +Curve -459 1392 -698 1350 +Curve -602 1334 -505 1318 +Curve -457 1306 -366 1346 +Curve -366 1346 -365 1346 +Curve -360 1349 -354 1351 +<-------EndPath +Path 4 4 0 -354 1351 +Curve -359 1358 -363 1365 +<-------EndPath +Path -1 4 0 -349 1353 +Curve -348 1354 -346 1354 +<-------EndPath +Path -1 4 -1 -346 1354 +Curve -346 1357 -345 1360 +Curve -344 1357 -342 1354 +<-------EndPath +Path -1 -1 0 -166 1345 +Curve -161 1323 -152 1306 +<-------EndPath +Path -1 -1 0 -169 1359 +Curve -170 1364 -170 1368 +Curve -170 1368 -170 1367 +Curve -169 1363 -168 1358 +Curve -168 1356 -167 1354 +Curve -167 1350 -166 1345 +<-------EndPath +Path 4 4 0 -176 1372 +Curve -176 1374 -176 1375 +<-------EndPath +Path 4 -1 0 -170 1369 +Curve -171 1369 -171 1369 +<-------EndPath +Path 4 -1 -1 -171 1369 +Curve -172 1370 -172 1370 +<-------EndPath +Path 4 4 0 -172 1370 +Curve -173 1373 -174 1376 +<-------EndPath +Path -1 -1 0 -171 1369 +Curve -171 1369 -170 1368 +Curve -171 1369 -171 1369 +<-------EndPath +Path -1 -1 0 -170 1369 +Curve -170 1368 -170 1367 +<-------EndPath +Path -1 -1 0 -165 1368 +Curve -166 1361 -167 1354 +<-------EndPath +Path 4 4 0 26 530 +Curve -23 517 -22 494 +<-------EndPath +!======EndShape +=======BeginShape +Path 0 19 0 1581 -1974 +Curve 1502 -2209 1742 -2358 +Curve 1886 -2447 1957 -2288 +Curve 1998 -2197 1999 -2124 +Curve 2011 -2548 2405 -2476 +Curve 2848 -2395 2498 -2129 +Curve 2777 -2211 2665 -1888 +Curve 2664 -1883 2662 -1878 +Curve 2661 -1876 2660 -1873 +Curve 2658 -1868 2656 -1862 +Curve 2655 -1860 2654 -1857 +Curve 2650 -1848 2645 -1839 +Curve 2645 -1838 2644 -1836 +Curve 2643 -1834 2642 -1832 +Curve 2641 -1830 2640 -1828 +Curve 2636 -1821 2632 -1813 +Curve 2632 -1812 2631 -1811 +Curve 2539 -1738 2447 -1665 +<-------EndPath +Path 0 0 0 2447 -1665 +Curve 2443 -1664 2439 -1662 +<-------EndPath +Path 0 2 -1 2439 -1662 +Curve 2752 -1649 3065 -1636 +<-------EndPath +Path 0 19 0 3065 -1636 +Curve 3131 -1670 3228 -1671 +Curve 3306 -1887 3449 -1712 +<-------EndPath +Path 0 3 0 3449 -1712 +Curve 3468 -1686 3487 -1660 +Curve 3475 -1782 3512 -1898 +<-------EndPath +Path 0 19 0 3512 -1898 +Curve 3533 -1965 3571 -2030 +Curve 3579 -2042 3586 -2054 +Curve 3589 -2058 3591 -2062 +Curve 3665 -2175 3758 -2049 +Curve 3720 -2328 3880 -2277 +Curve 3963 -2250 4098 -2135 +<-------EndPath +Path 0 -1 1 4098 -2135 +Curve 4098 -2470 4098 -2804 +<-------EndPath +Path 0 2 -1 4098 -2804 +Curve 4019 -2812 3939 -2820 +Curve 3519 -2864 3098 -2907 +Curve 3101 -2908 3103 -2909 +Curve 3151 -2911 3198 -2912 +Curve 3657 -2921 4098 -2990 +<-------EndPath +Path 0 -1 1 4098 -2990 +Curve 4098 -3040 4098 -3089 +Curve 147 -3089 -3805 -3089 +<-------EndPath +Path 0 2 -1 -3805 -3089 +Curve -3986 -3039 -4161 -2972 +<-------EndPath +Path 0 -1 1 -4161 -2972 +Curve -4161 -2567 -4161 -2161 +<-------EndPath +Path 0 2 -1 -4161 -2161 +Curve -3659 -2058 -3147 -2006 +Curve -2519 -1950 -1890 -1893 +Curve -1890 -1894 -1890 -1895 +<-------EndPath +Path 0 19 0 -1890 -1895 +Curve -1900 -1977 -1826 -2126 +Curve -1825 -2128 -1824 -2129 +Curve -1820 -2137 -1816 -2145 +Curve -1667 -2429 -1470 -2270 +Curve -1465 -2310 -1453 -2343 +<-------EndPath +Path 0 2 -1 -1453 -2343 +Curve -1745 -2346 -2036 -2348 +Curve -2571 -2351 -3101 -2424 +Curve -2581 -2437 -2062 -2400 +Curve -1755 -2379 -1448 -2357 +<-------EndPath +Path 0 19 0 -1448 -2357 +Curve -1363 -2558 -1000 -2471 +Curve -861 -2438 -755 -2399 +Curve -737 -2494 -681 -2512 +Curve -675 -2514 -668 -2515 +Curve -652 -2515 -635 -2514 +Curve -633 -2514 -631 -2514 +Curve -550 -2500 -419 -2383 +Curve -300 -2277 -444 -2174 +Curve -444 -2173 -443 -2171 +Curve -443 -2170 -442 -2169 +Curve -438 -2147 -433 -2125 +<-------EndPath +Path 0 19 -1 -433 -2125 +Curve -433 -2122 -433 -2118 +<-------EndPath +Path 0 19 0 -433 -2118 +Curve -432 -2049 -486 -1970 +Curve -222 -2104 -56 -2015 +Curve 7 -2282 213 -1989 +Curve 215 -1987 217 -1984 +Curve 245 -1943 254 -1899 +Curve 266 -1841 245 -1778 +<-------EndPath +Path 0 2 -1 245 -1778 +Curve 242 -1769 238 -1760 +Curve 356 -1754 474 -1748 +<-------EndPath +Path 0 19 0 474 -1748 +Curve 522 -2045 729 -2014 +<-------EndPath +Path 0 3 0 729 -2014 +Curve 735 -2013 740 -2012 +<-------EndPath +Path 0 19 0 740 -2012 +Curve 777 -2006 818 -1989 +Curve 790 -2016 762 -2043 +Curve 644 -2178 947 -2151 +<-------EndPath +Path 0 19 -1 947 -2151 +Curve 995 -2146 1043 -2140 +<-------EndPath +Path 0 19 0 1043 -2140 +Curve 1046 -2140 1049 -2139 +Curve 1063 -2137 1076 -2134 +<-------EndPath +Path 0 3 -1 1076 -2134 +Curve 1089 -2132 1101 -2130 +Curve 1101 -2130 1101 -2129 +<-------EndPath +Path 0 19 0 1101 -2129 +Curve 1121 -2125 1141 -2120 +Curve 1251 -2089 1311 -2026 +<-------EndPath +Path 0 19 -1 1311 -2026 +Curve 1313 -2024 1315 -2021 +<-------EndPath +Path 0 19 0 1315 -2021 +Curve 1331 -1999 1347 -1976 +Curve 1384 -1908 1377 -1812 +Curve 1487 -1853 1640 -1852 +Curve 1638 -1856 1636 -1859 +Curve 1635 -1861 1634 -1862 +Curve 1608 -1906 1591 -1947 +<-------EndPath +Path 0 3 -1 1591 -1947 +Curve 1586 -1961 1581 -1974 +<-------EndPath +Path 19 3 0 1581 -1974 +Curve 1586 -1961 1591 -1947 +<-------EndPath +Path 2 0 -1 1708 -2594 +Curve 1093 -2637 478 -2679 +Curve 156 -2694 -167 -2709 +Curve -207 -2707 -247 -2704 +Curve -290 -2702 -332 -2699 +Curve 236 -2659 803 -2618 +Curve 1383 -2575 1962 -2531 +Curve 2563 -2494 3163 -2456 +Curve 3371 -2448 3578 -2439 +Curve 3176 -2478 2773 -2516 +Curve 2241 -2555 1708 -2594 +<-------EndPath +Path 19 3 -1 740 -2012 +Curve 734 -2006 728 -1999 +Curve 729 -2007 729 -2014 +<-------EndPath +Path 19 3 0 1101 -2129 +Curve 1089 -2132 1076 -2134 +<-------EndPath +Path 19 2 0 474 -1748 +Curve 473 -1743 472 -1738 +Curve 415 -1365 738 -1429 +Curve 534 -1333 718 -1139 +Curve 719 -1139 719 -1138 +Curve 718 -1137 717 -1135 +Curve 711 -1126 705 -1117 +Curve 689 -1090 672 -1062 +Curve 545 -840 543 -590 +Curve 541 -383 624 -158 +Curve 524 -295 399 -355 +<-------EndPath +Path 19 1 0 399 -355 +Curve 399 -355 398 -355 +<-------EndPath +Path 19 3 -1 398 -355 +Curve 393 -354 387 -352 +Curve 387 -357 386 -361 +<-------EndPath +Path 19 2 0 386 -361 +Curve 355 -372 324 -383 +Curve 266 -400 204 -402 +Curve 214 -411 224 -419 +Curve 262 -456 273 -490 +Curve 287 -539 246 -583 +Curve 211 -625 176 -666 +Curve -58 -969 126 -1182 +Curve 140 -1200 154 -1217 +Curve 155 -1219 156 -1220 +Curve 220 -1312 212 -1398 +Curve 198 -1540 171 -1650 +Curve 224 -1716 245 -1778 +<-------EndPath +Path 3 2 0 399 -356 +Curve 393 -359 386 -361 +<-------EndPath +Path 3 3 0 386 -361 +Curve 392 -358 398 -355 +<-------EndPath +Path 3 1 -1 398 -355 +Curve 399 -356 399 -356 +<-------EndPath +Path 2 1 -1 399 -356 +Curve 399 -356 399 -355 +<-------EndPath +Path 2 2 0 224 -419 +Curve 274 -401 324 -383 +<-------EndPath +Path 19 0 -1 2439 -1662 +Curve 2443 -1664 2447 -1665 +<-------EndPath +Path 2 19 0 2439 -1662 +Curve 2409 -1656 2378 -1649 +Curve 2637 -1608 2442 -1372 +Curve 2507 -1167 2298 -1009 +Curve 2743 -710 2498 -209 +Curve 3135 -462 2987 -974 +Curve 2831 -1515 3065 -1636 +<-------EndPath +Path -1 2 1 4098 -2990 +Curve 4098 -2897 4098 -2804 +<-------EndPath +Path -1 19 1 4098 -1949 +Curve 4098 -1651 4098 -1352 +<-------EndPath +Path -1 -1 0 4098 -1352 +Curve 4223 -1294 4098 -1249 +<-------EndPath +Path -1 19 1 4098 -1249 +Curve 4098 -119 4098 1011 +<-------EndPath +Path -1 11 1 4098 1011 +Curve 4098 1081 4098 1151 +<-------EndPath +Path -1 8 1 4098 1151 +Curve 4098 1789 4098 2427 +<-------EndPath +Path -1 -1 1 4098 2427 +Curve 4106 2427 4113 2427 +<-------EndPath +Path -1 19 1 4098 -1352 +Curve 4098 -1301 4098 -1249 +<-------EndPath +Path 2 3 0 3487 -1660 +Curve 3489 -1645 3491 -1629 +Curve 3501 -1626 3511 -1623 +Curve 3499 -1642 3487 -1660 +<-------EndPath +Path 19 3 -1 3512 -1898 +Curve 3600 -1628 3566 -1406 +Curve 3561 -1375 3528 -1374 +Curve 3374 -1369 3406 -1535 +Curve 3424 -1625 3449 -1712 +<-------EndPath +Path -1 19 0 4098 -2135 +Curve 4098 -2042 4098 -1949 +<-------EndPath +Path 8 11 -1 3811 1475 +Curve 3814 1478 3817 1480 +Curve 3651 1490 3485 1499 +Curve 3457 1503 3429 1507 +Curve 3462 1510 3495 1513 +Curve 3694 1501 3879 1567 +Curve 3922 1582 3960 1603 +Curve 3971 1609 3977 1625 +Curve 3341 1710 2710 1662 +Curve 3286 1630 3861 1598 +Curve 3429 1501 2976 1518 +Curve 2976 1516 2976 1513 +Curve 3065 1507 3153 1501 +Curve 3347 1483 3540 1464 +Curve 3676 1470 3811 1475 +<-------EndPath +Path 14 8 -1 4098 2450 +Curve 4096 2450 4094 2450 +Curve 3473 2429 2848 2413 +<-------EndPath +Path 14 14 1 2848 2413 +Curve 2899 2466 2944 2532 +<-------EndPath +Path 14 5 1 2944 2532 +Curve 2948 2538 2952 2544 +<-------EndPath +Path 14 12 1 2952 2544 +Curve 3525 2559 4098 2574 +<-------EndPath +Path 14 -1 1 4098 2574 +Curve 4098 2512 4098 2450 +<-------EndPath +Path 8 -1 1 4098 2450 +Curve 4098 2439 4098 2427 +<-------EndPath +Path 8 8 1 4098 2427 +Curve 1010 2339 -2078 2251 +Curve -2100 2262 -2122 2272 +<-------EndPath +Path 8 15 -1 -2122 2272 +Curve -2087 2274 -2051 2275 +<-------EndPath +Path 8 14 1 -2051 2275 +Curve -2028 2276 -2004 2277 +<-------EndPath +Path 8 14 -1 -2004 2277 +Curve -1223 2303 -442 2328 +Curve -80 2338 283 2348 +<-------EndPath +Path 8 14 1 283 2348 +Curve 287 2348 291 2348 +<-------EndPath +Path 8 14 -1 291 2348 +Curve 715 2360 1138 2371 +Curve 1626 2383 2113 2395 +Curve 2481 2404 2848 2413 +<-------EndPath +Path -1 -1 1 4098 2833 +Curve 4106 2833 4113 2833 +<-------EndPath +Path -1 16 1 4098 2833 +Curve 4098 2840 4098 2846 +<-------EndPath +Path -1 17 1 4098 2846 +Curve 4098 3683 4098 4519 +Curve -32 4519 -4161 4519 +Curve -4161 3607 -4161 2695 +<-------EndPath +Path -1 16 1 -4161 2695 +Curve -4161 2635 -4161 2574 +<-------EndPath +Path -1 12 1 -4161 2574 +Curve -4161 2468 -4161 2361 +<-------EndPath +Path -1 13 1 -4161 2361 +Curve -4161 2277 -4161 2193 +<-------EndPath +Path -1 8 1 -4161 2193 +Curve -4161 2193 -4161 2192 +Curve -4161 1994 -4161 1795 +<-------EndPath +Path -1 9 1 -4161 1795 +Curve -4161 1745 -4161 1694 +<-------EndPath +Path -1 8 1 -4161 1694 +Curve -4161 1403 -4161 1111 +<-------EndPath +Path -1 11 1 -4161 1111 +Curve -4161 991 -4161 871 +<-------EndPath +Path -1 19 1 -4161 871 +Curve -4161 171 -4161 -529 +<-------EndPath +Path -1 0 1 -4161 -529 +Curve -4161 -609 -4161 -689 +<-------EndPath +Path -1 2 1 -4161 -689 +Curve -4161 -1006 -4161 -1322 +<-------EndPath +Path -1 0 1 -4161 -1322 +Curve -4161 -1515 -4161 -1708 +<-------EndPath +Path -1 2 1 -4161 -1708 +Curve -4161 -1935 -4161 -2161 +<-------EndPath +Path -1 12 1 4098 2574 +Curve 4098 2618 4098 2662 +<-------EndPath +Path -1 -1 1 4098 2662 +Curve 4106 2662 4113 2662 +<-------EndPath +Path -1 12 1 4098 2662 +Curve 4098 2704 4098 2745 +<-------EndPath +Path -1 16 1 4098 2745 +Curve 4098 2789 4098 2833 +<-------EndPath +Path 16 17 -1 -1748 2624 +Curve -1748 2637 -1748 2650 +Curve -2089 2950 -2154 2993 +Curve -2220 3036 -1836 3056 +Curve -1387 3085 -937 3113 +Curve -422 3150 136 3135 +Curve 693 3119 1028 3145 +Curve 1363 3170 1454 3139 +Curve 1545 3108 1693 2941 +Curve 1840 2773 2055 2789 +Curve 2269 2804 1898 2769 +Curve 2454 2780 2621 2776 +Curve 2765 2772 2908 2768 +Curve 2910 2768 2912 2768 +Curve 2942 2767 2972 2766 +Curve 2980 2766 2988 2766 +Curve 3077 2762 3166 2758 +Curve 3299 2752 3431 2761 +Curve 3563 2769 3695 2792 +Curve 3897 2819 4098 2846 +<-------EndPath +Path 8 11 -1 2179 1609 +Curve 2117 1617 2054 1625 +Curve 1711 1696 1383 1609 +Curve 1376 1600 1368 1591 +Curve 1365 1584 1361 1577 +Curve 1362 1573 1362 1568 +Curve 1445 1554 1527 1539 +Curve 1070 1456 603 1470 +Curve 418 1475 232 1480 +Curve 239 1474 245 1467 +Curve 260 1456 277 1450 +Curve 282 1448 286 1446 +Curve 287 1445 288 1443 +Curve 877 1436 1460 1505 +Curve 1543 1517 1626 1529 +Curve 1623 1534 1619 1538 +Curve 1506 1572 1388 1582 +Curve 1438 1588 1488 1594 +Curve 1798 1601 2106 1580 +Curve 2152 1576 2179 1609 +<-------EndPath +Path 10 8 -1 2389 1389 +Curve 2466 1390 2543 1391 +Curve 2466 1388 2388 1384 +Curve 1761 1373 1133 1371 +Curve 1686 1392 2238 1389 +Curve 2314 1389 2389 1389 +<-------EndPath +Path 11 4 -1 685 954 +Curve 685 957 685 959 +<-------EndPath +Path 11 7 0 685 959 +Curve 682 959 679 959 +<-------EndPath +Path 11 19 0 679 959 +Curve -310 940 -1298 920 +<-------EndPath +Path 11 7 0 -1298 920 +Curve -1308 920 -1318 919 +<-------EndPath +Path 11 4 -1 -1318 919 +Curve -1318 919 -1318 918 +<-------EndPath +Path 11 19 0 -1318 918 +Curve -2740 895 -4161 871 +<-------EndPath +Path 7 4 -1 685 959 +Curve 682 959 679 959 +<-------EndPath +Path 19 4 -1 679 959 +Curve 680 957 680 954 +<-------EndPath +Path 19 4 0 680 954 +Curve 683 954 685 954 +<-------EndPath +Path 19 11 0 685 954 +Curve 2392 983 4098 1011 +<-------EndPath +Path 8 4 -1 649 1140 +Curve 653 1140 656 1140 +Curve 653 1140 649 1140 +<-------EndPath +Path 8 11 -1 649 1140 +Curve -145 1134 -938 1128 +<-------EndPath +Path 8 6 -1 -938 1128 +Curve -943 1128 -947 1128 +<-------EndPath +Path 8 11 -1 -947 1128 +Curve -1155 1127 -1363 1125 +<-------EndPath +Path 8 4 -1 -1363 1125 +Curve -1374 1125 -1384 1125 +Curve -1384 1125 -1384 1124 +<-------EndPath +Path 8 11 -1 -1384 1124 +Curve -2773 1118 -4161 1111 +<-------EndPath +Path 8 11 -1 642 1208 +Curve 757 1186 851 1246 +Curve 863 1254 874 1261 +Curve 863 1264 852 1267 +Curve 479 1212 92 1278 +Curve 63 1278 33 1277 +Curve 246 1252 459 1226 +Curve 551 1217 642 1208 +<-------EndPath +Path 11 8 -1 649 1140 +Curve 649 1138 649 1135 +Curve 2374 1143 4098 1151 +<-------EndPath +Path 9 8 -1 -4161 1795 +Curve -3724 1814 -3286 1832 +Curve -2756 1853 -2226 1873 +Curve -1943 1883 -1660 1892 +Curve -1374 1902 -1087 1911 +Curve -960 1916 -833 1920 +Curve -475 1929 -117 1937 +Curve 24 1940 164 1942 +Curve 716 1954 1268 1966 +Curve 1273 1966 1277 1966 +Curve 1760 1988 2243 2010 +Curve 2590 2032 2948 2031 +Curve 2113 1950 1278 1940 +Curve 1273 1940 1268 1940 +Curve 716 1914 164 1888 +Curve -334 1860 -832 1831 +Curve -1245 1810 -1657 1788 +Curve -2049 1766 -2441 1744 +Curve -3131 1717 -3821 1706 +Curve -3989 1700 -4157 1694 +Curve -4159 1694 -4161 1694 +<-------EndPath +Path 14 14 1 283 2348 +Curve 247 2390 258 2468 +Curve 257 2472 255 2475 +<-------EndPath +Path 14 12 1 255 2475 +Curve 1599 2510 2942 2544 +<-------EndPath +Path 14 5 1 2942 2544 +Curve 2943 2538 2944 2532 +<-------EndPath +Path 16 16 1 223 2665 +Curve 223 2673 223 2681 +<-------EndPath +Path 12 12 1 223 2665 +Curve 219 2554 255 2475 +<-------EndPath +Path 12 14 1 255 2475 +Curve -997 2443 -2249 2410 +<-------EndPath +Path 12 5 1 -2249 2410 +Curve -2253 2416 -2256 2422 +<-------EndPath +Path 12 15 1 -2256 2422 +Curve -2250 2503 -2244 2584 +<-------EndPath +Path 12 16 1 -2244 2584 +Curve -2244 2599 -2243 2614 +Curve -2054 2618 -1864 2622 +<-------EndPath +Path 12 17 1 -1864 2622 +Curve -1806 2623 -1748 2624 +<-------EndPath +Path 12 16 1 -1748 2624 +Curve -1712 2625 -1676 2626 +<-------EndPath +Path 12 5 1 -1676 2626 +Curve -1664 2626 -1651 2626 +<-------EndPath +Path 12 16 1 -1651 2626 +Curve -714 2646 223 2665 +Curve 1287 2687 2350 2709 +<-------EndPath +Path 12 12 1 2350 2709 +Curve 2370 2690 2390 2671 +<-------EndPath +Path 5 8 -1 2963 2038 +Curve 3003 2040 3043 2041 +Curve 3018 2039 2993 2036 +Curve 2978 2036 2963 2036 +Curve 2963 2037 2963 2038 +<-------EndPath +Path 12 12 1 2942 2544 +Curve 2941 2552 2940 2560 +<-------EndPath +Path 12 15 1 2940 2560 +Curve 2972 2620 2983 2706 +<-------EndPath +Path 12 5 1 2983 2706 +Curve 2984 2714 2984 2722 +<-------EndPath +Path 12 16 1 2984 2722 +Curve 3541 2734 4098 2745 +<-------EndPath +Path 5 12 1 2942 2544 +Curve 2947 2544 2952 2544 +<-------EndPath +Path 16 15 -1 2925 2698 +Curve 2920 2697 2915 2696 +<-------EndPath +Path 16 12 1 2915 2696 +Curve 2914 2701 2912 2705 +Curve 2910 2713 2908 2720 +<-------EndPath +Path 16 16 1 2908 2720 +Curve 2908 2728 2908 2736 +<-------EndPath +Path 16 15 1 2938 2711 +Curve 2933 2706 2927 2701 +Curve 2926 2700 2925 2698 +<-------EndPath +Path 5 15 -1 2983 2706 +Curve 2965 2710 2947 2713 +Curve 2943 2712 2938 2711 +<-------EndPath +Path 5 16 1 2938 2711 +Curve 2940 2713 2941 2714 +Curve 2946 2718 2950 2721 +Curve 2961 2728 2971 2735 +<-------EndPath +Path 5 16 -1 2971 2735 +Curve 2978 2729 2984 2722 +<-------EndPath +Path 16 16 1 2984 2722 +Curve 2985 2729 2985 2735 +<-------EndPath +Path 15 12 1 2940 2560 +Curve 2931 2634 2915 2696 +<-------EndPath +Path 12 16 1 2350 2709 +Curve 2629 2715 2908 2720 +<-------EndPath +Path -1 2 1 -4161 -2972 +Curve -4161 -3031 -4161 -3089 +Curve -3983 -3089 -3805 -3089 +<-------EndPath +Path 2 19 0 -3530 -1596 +Curve -3478 -1603 -3429 -1577 +<-------EndPath +Path 2 0 -1 -3429 -1577 +Curve -3416 -1574 -3403 -1571 +<-------EndPath +Path 2 19 0 -3403 -1571 +Curve -3473 -1743 -3153 -1823 +Curve -2750 -1924 -2803 -1637 +Curve -2812 -1573 -2821 -1509 +Curve -2666 -1432 -2613 -1335 +<-------EndPath +Path 2 0 -1 -2613 -1335 +Curve -2391 -1239 -2254 -1045 +Curve -2089 -812 -2297 -616 +Curve -2365 -551 -2444 -507 +<-------EndPath +Path 2 19 0 -2444 -507 +Curve -2454 -389 -2534 -240 +Curve -1946 -188 -2238 48 +Curve -2331 123 -2378 174 +Curve -2470 272 -2392 279 +Curve -2418 243 -2261 241 +Curve -2099 239 -1921 -78 +Curve -1862 -183 -1784 -212 +Curve -1628 -272 -1394 -24 +<-------EndPath +Path 2 2 0 -1394 -24 +Curve -1394 -24 -1393 -24 +<-------EndPath +Path 2 19 0 -1393 -24 +Curve -1504 -211 -1521 -331 +Curve -1544 -493 -1400 -533 +Curve -1400 -534 -1399 -534 +Curve -1349 -541 -1299 -547 +Curve -1343 -566 -1386 -585 +Curve -1396 -589 -1405 -593 +Curve -2072 -899 -1557 -1459 +Curve -1495 -1521 -1433 -1582 +Curve -1385 -1626 -1322 -1629 +Curve -1372 -1752 -1406 -1857 +<-------EndPath +Path 2 0 -1 -1406 -1857 +Curve -1408 -1858 -1410 -1858 +<-------EndPath +Path 2 19 0 -1410 -1858 +Curve -1489 -1838 -1568 -1817 +Curve -1873 -1743 -1890 -1895 +<-------EndPath +Path 0 2 -1 -3530 -1596 +Curve -3526 -1597 -3521 -1597 +Curve -3599 -1612 -3676 -1627 +Curve -3919 -1668 -4161 -1708 +<-------EndPath +Path 0 19 0 -3429 -1577 +Curve -3414 -1568 -3399 -1558 +Curve -3398 -1557 -3396 -1556 +Curve -3400 -1564 -3403 -1571 +<-------EndPath +Path 19 0 0 -3530 -1596 +Curve -3671 -1478 -3811 -1360 +Curve -3813 -1358 -3814 -1355 +Curve -3819 -1349 -3823 -1342 +Curve -3840 -1316 -3857 -1290 +<-------EndPath +Path 19 0 -1 -3857 -1290 +Curve -3862 -1282 -3867 -1273 +Curve -3868 -1273 -3868 -1273 +<-------EndPath +Path 19 2 0 -3868 -1273 +Curve -3881 -1252 -3894 -1230 +<-------EndPath +Path 19 3 -1 -3894 -1230 +Curve -3891 -1236 -3887 -1241 +Curve -3754 -1209 -3622 -1166 +Curve -3609 -1162 -3596 -1154 +Curve -3592 -1147 -3588 -1139 +Curve -3582 -1117 -3575 -1094 +Curve -3571 -1071 -3581 -1049 +Curve -3584 -1042 -3586 -1034 +Curve -3729 -957 -3899 -998 +Curve -3948 -1006 -3996 -1013 +Curve -4003 -1014 -4009 -1014 +<-------EndPath +Path 19 2 0 -4009 -1014 +Curve -4084 -854 -4125 -697 +<-------EndPath +Path 19 0 0 -4125 -697 +Curve -4148 -613 -4161 -529 +<-------EndPath +Path 0 0 0 -3868 -1273 +Curve -3863 -1282 -3857 -1290 +<-------EndPath +Path 2 3 0 -4009 -1014 +Curve -3952 -1122 -3894 -1230 +<-------EndPath +Path 2 0 -1 -3868 -1273 +Curve -3963 -1290 -4057 -1306 +Curve -4109 -1314 -4161 -1322 +<-------EndPath +Path 2 0 -1 -4161 -689 +Curve -4159 -690 -4157 -691 +Curve -4147 -694 -4136 -697 +Curve -4131 -697 -4125 -697 +<-------EndPath +Path 2 19 0 -1453 -2343 +Curve -1451 -2350 -1448 -2357 +<-------EndPath +Path 19 3 -1 -622 -1984 +Curve -620 -1989 -618 -1993 +Curve -616 -1993 -614 -1992 +Curve -617 -1989 -619 -1986 +Curve -621 -1985 -622 -1984 +<-------EndPath +Path 2 0 -1 -2656 -841 +Curve -2631 -853 -2606 -864 +Curve -2610 -870 -2614 -875 +Curve -2672 -908 -2730 -941 +<-------EndPath +Path 2 19 0 -2730 -941 +Curve -2756 -915 -2781 -889 +Curve -2711 -868 -2656 -841 +<-------EndPath +Path 0 19 0 -2656 -841 +Curve -2426 -730 -2444 -507 +<-------EndPath +Path 0 19 0 -2613 -1335 +Curve -2521 -1168 -2730 -941 +<-------EndPath +Path 19 2 0 -486 -1970 +Curve -484 -1960 -482 -1949 +Curve -542 -1929 -562 -1929 +Curve -536 -1944 -510 -1958 +Curve -504 -1962 -497 -1965 +Curve -492 -1968 -486 -1970 +<-------EndPath +Path 19 0 0 -1410 -1858 +Curve -1408 -1859 -1406 -1859 +Curve -1406 -1858 -1406 -1857 +<-------EndPath +Path -1 19 -1 -1241 -1614 +Curve -1243 -1613 -1244 -1612 +Curve -1244 -1610 -1243 -1608 +Curve -1224 -1527 -1204 -1445 +<-------EndPath +Path -1 19 0 -1204 -1445 +Curve -1222 -1525 -1239 -1605 +Curve -1240 -1607 -1240 -1608 +Curve -1241 -1611 -1241 -1614 +<-------EndPath +Path 19 3 -1 -1399 -531 +Curve -1400 -532 -1400 -533 +Curve -1400 -533 -1399 -533 +Curve -1399 -532 -1399 -531 +<-------EndPath +Path 2 19 0 -1394 -24 +Curve -1390 -17 -1385 -10 +Curve -1389 -17 -1393 -24 +<-------EndPath +Path 19 18 0 -559 926 +Curve -642 159 -679 32 +Curve -731 -154 -694 -336 +Curve -656 -521 -676 -711 +Curve -694 -878 -732 -1041 +Curve -706 -975 -674 -917 +Curve -592 -771 -604 -570 +Curve -614 -384 -601 -199 +Curve -488 -197 -417 -253 +Curve -480 -184 -543 -114 +Curve -671 37 -555 204 +Curve -513 264 -422 929 +<-------EndPath +Path 19 18 -1 -422 929 +Curve -491 928 -559 926 +<-------EndPath +Path 7 19 0 -1298 918 +Curve -1308 918 -1318 918 +<-------EndPath +Path 7 4 -1 -1318 918 +Curve -1318 919 -1318 919 +<-------EndPath +Path 7 19 -1 -1298 920 +Curve -1298 919 -1298 918 +<-------EndPath +Path 11 6 -1 -947 1128 +Curve -947 1128 -946 1127 +Curve -942 1128 -938 1128 +<-------EndPath +Path 4 11 -1 -1363 1125 +Curve -1374 1125 -1384 1124 +<-------EndPath +Path 8 11 -1 -2987 1315 +Curve -2383 1326 -1787 1411 +Curve -1784 1414 -1781 1416 +Curve -1787 1418 -1792 1420 +Curve -1958 1434 -2124 1448 +Curve -1281 1432 -454 1438 +Curve -1393 1537 -2290 1443 +Curve -2290 1439 -2289 1435 +Curve -2190 1423 -2091 1411 +Curve -2705 1293 -3328 1384 +Curve -3404 1398 -3479 1411 +Curve -3488 1418 -3497 1425 +Curve -3508 1432 -3518 1438 +Curve -3521 1434 -3523 1430 +Curve -3513 1411 -3496 1395 +Curve -3491 1390 -3485 1384 +Curve -3398 1371 -3311 1358 +Curve -3177 1342 -3042 1325 +Curve -3015 1320 -2987 1315 +<-------EndPath +Path 5 15 1 -2249 2410 +Curve -2253 2410 -2257 2410 +Curve -2257 2416 -2256 2422 +<-------EndPath +Path 5 12 1 -2325 2409 +Curve -2325 2410 -2324 2410 +<-------EndPath +Path 5 15 1 -2324 2410 +Curve -2324 2410 -2323 2409 +<-------EndPath +Path 5 13 1 -2323 2409 +Curve -2324 2409 -2325 2409 +<-------EndPath +Path 12 13 1 -2325 2409 +Curve -3243 2385 -4161 2361 +<-------EndPath +Path 12 12 1 -2341 2424 +Curve -2333 2417 -2324 2410 +<-------EndPath +Path 15 12 1 -2324 2410 +Curve -2302 2501 -2299 2613 +<-------EndPath +Path 15 5 1 -2299 2613 +Curve -2299 2617 -2299 2621 +<-------EndPath +Path 15 16 1 -2299 2621 +Curve -2277 2607 -2254 2593 +Curve -2249 2589 -2244 2584 +<-------EndPath +Path 14 15 1 -2051 2275 +Curve -2179 2298 -2249 2410 +<-------EndPath +Path 13 8 -1 -2122 2272 +Curve -2239 2267 -2356 2262 +Curve -3254 2228 -4151 2193 +Curve -4156 2193 -4161 2193 +<-------EndPath +Path 15 13 1 -2122 2272 +Curve -2226 2323 -2323 2409 +<-------EndPath +Path 5 16 1 -2301 2622 +Curve -2300 2622 -2299 2621 +<-------EndPath +Path 16 5 -1 -2301 2622 +Curve -2301 2618 -2301 2613 +<-------EndPath +Path 16 12 1 -2301 2613 +Curve -3231 2594 -4161 2574 +<-------EndPath +Path 16 16 1 -2313 2627 +Curve -2307 2625 -2301 2622 +<-------EndPath +Path 16 17 -1 -4161 2695 +Curve -4155 2695 -4149 2695 +Curve -3901 2646 -3630 2650 +Curve -3371 2660 -3111 2669 +Curve -2841 2686 -2565 2684 +Curve -2438 2679 -2310 2673 +Curve -2303 2673 -2296 2672 +Curve -2161 2656 -2026 2639 +Curve -1945 2631 -1864 2622 +<-------EndPath +Path 5 12 1 -2299 2613 +Curve -2300 2613 -2301 2613 +<-------EndPath +Path 16 5 -1 -1651 2626 +Curve -1651 2627 -1651 2628 +<-------EndPath +Path 16 5 1 -1651 2628 +Curve -1664 2627 -1676 2626 +<-------EndPath +Path 8 8 1 -2078 2251 +Curve -3120 2222 -4161 2192 +<-------EndPath +!======EndShape +=======BeginShape +Path 2 0 -1 169 -1261 +Curve 341 -1240 513 -1218 +Curve 497 -944 352 -711 +Curve 403 -692 453 -673 +Curve 516 -719 578 -765 +Curve 904 -584 962 -215 +Curve 1013 -322 1064 -428 +Curve 1059 -804 685 -827 +Curve 659 -827 633 -827 +Curve 835 -1201 499 -1314 +Curve 353 -1363 202 -1319 +Curve 186 -1290 169 -1261 +<-------EndPath +Path 0 0 0 37 -1420 +Curve 16 -1345 4 -1268 +<-------EndPath +Path 0 -1 0 1122 -438 +Curve 1441 -514 1294 -999 +Curve 1150 -1470 784 -1308 +Curve 1009 -1495 741 -1765 +Curve 378 -2131 134 -1663 +Curve 72 -1544 37 -1420 +Curve 75 -1720 -121 -1957 +Curve -484 -2397 -636 -1928 +Curve -598 -2186 -919 -2298 +Curve -1502 -2501 -1375 -2063 +Curve -1352 -1982 -1236 -2008 +Curve -1504 -1922 -1439 -1587 +Curve -1386 -1318 -1055 -1274 +Curve -1009 -1271 -962 -1268 +Curve -1252 -1264 -1341 -918 +Curve -1457 -471 -916 -464 +Curve -911 -464 -906 -464 +Curve -821 -476 -736 -488 +Curve -816 -464 -906 -464 +Curve -1229 -389 -1064 -125 +Curve -987 -2 -796 6 +Curve -656 9 -516 12 +Curve -721 106 -902 364 +Curve -1208 800 -677 768 +Curve -588 762 -496 732 +Curve -462 676 -482 614 +Curve -402 604 -386 569 +<-------EndPath +Path 0 1 0 -386 569 +Curve -386 551 -386 533 +Curve -383 228 -379 -77 +Curve -372 -518 -610 -1384 +<-------EndPath +Path 0 0 0 -610 -1384 +Curve -631 -1438 -652 -1491 +<-------EndPath +Path 0 -1 0 -112 476 +Curve -246 948 237 891 +Curve 384 874 415 798 +Curve 394 752 404 672 +Curve 435 748 415 798 +Curve 472 928 773 788 +Curve 1268 558 864 292 +Curve 1317 342 1430 -88 +Curve 1538 -498 1122 -438 +<-------EndPath +Path 0 0 0 1122 -438 +Curve 1093 -433 1064 -428 +<-------EndPath +Path 1 0 0 -112 476 +Curve -66 416 -9 366 +Curve 229 158 404 -68 +Curve 165 67 -132 200 +Curve -224 -29 -1 -347 +Curve -132 -191 -176 -189 +Curve -309 -298 -314 -455 +Curve -319 -612 -610 -1384 +<-------EndPath +Path -1 1 0 -112 476 +Curve -264 672 -294 970 +Curve -296 990 -298 1010 +Curve -298 1013 -297 1015 +Curve -260 1332 -237 1732 +Curve -213 2143 -43 2262 +<-------EndPath +Path -1 1 -1 -43 2262 +Curve -72 2290 -101 2317 +<-------EndPath +Path -1 1 0 -101 2317 +Curve -334 2016 -385 2362 +Curve -459 2097 -732 2350 +Curve -734 2352 -736 2354 +<-------EndPath +Path -1 1 -1 -736 2354 +Curve -808 2333 -880 2312 +<-------EndPath +Path -1 1 0 -880 2312 +Curve -487 2266 -437 1890 +Curve -428 1820 -412 1756 +Curve -408 1724 -403 1692 +Curve -362 1354 -542 1137 +Curve -385 1139 -386 751 +Curve -386 660 -386 569 +<-------EndPath +Path 0 0 0 123 -504 +Curve 61 -426 -1 -347 +<-------EndPath +!======EndShape +=======BeginShape +Path 1 0 -1 -2346 -172 +Curve -2562 -273 -2770 -361 +Curve -2463 -421 -2134 -470 +Curve -2091 -477 -2048 -483 +Curve -1930 -500 -1827 -542 +Curve -1798 -554 -1769 -566 +Curve -1767 -567 -1764 -568 +Curve -1615 -636 -1488 -731 +Curve -1353 -833 -1139 -880 +Curve -1110 -886 -1080 -892 +Curve -850 -941 -608 -965 +Curve -520 -973 -432 -980 +Curve -466 -1266 -306 -1278 +Curve -282 -1277 -257 -1276 +Curve -224 -1268 -191 -1260 +Curve -5 -1226 181 -1192 +Curve 192 -1190 202 -1188 +Curve 357 -1162 511 -1135 +Curve 624 -1116 737 -1096 +Curve 953 -1058 1169 -1020 +Curve 982 -910 1234 -866 +Curve 1244 -865 1253 -863 +Curve 1260 -862 1266 -861 +Curve 1927 -759 2569 -560 +Curve 2337 -484 1974 -484 +Curve 1814 -491 1653 -498 +Curve 1694 -393 1756 -308 +<-------EndPath +Path 1 -1 -1 1756 -308 +Curve 1702 -421 1973 -406 +Curve 2268 -393 2562 -380 +Curve 2689 -376 2816 -371 +Curve 3308 -356 2831 -630 +Curve 2711 -653 2591 -675 +Curve 1765 -829 1270 -889 +Curve 1258 -891 1246 -893 +Curve 1244 -894 1241 -894 +Curve 1239 -895 1236 -896 +Curve 1196 -907 1166 -933 +Curve 1181 -933 1195 -932 +Curve 1206 -932 1216 -932 +Curve 1219 -932 1222 -932 +Curve 1247 -932 1272 -932 +Curve 2042 -934 1480 -1038 +Curve 1338 -1066 1195 -1094 +Curve 1195 -1095 1194 -1095 +Curve 1194 -1095 1193 -1095 +Curve 970 -1126 747 -1156 +Curve 633 -1173 519 -1190 +Curve 408 -1211 303 -1241 +Curve 260 -1255 217 -1268 +Curve 35 -1328 -209 -1326 +Curve -232 -1329 -254 -1331 +Curve -279 -1332 -304 -1333 +Curve -306 -1333 -307 -1333 +Curve -309 -1333 -310 -1333 +Curve -554 -1329 -554 -1103 +Curve -554 -1062 -588 -1049 +Curve -602 -1047 -615 -1044 +Curve -858 -1020 -1100 -996 +Curve -1346 -966 -1590 -900 +Curve -1978 -795 -1689 -636 +Curve -1727 -608 -1774 -587 +Curve -1776 -586 -1777 -585 +Curve -1887 -539 -2047 -534 +Curve -2096 -535 -2144 -535 +Curve -2405 -547 -2788 -477 +Curve -2790 -477 -2792 -476 +Curve -2855 -464 -2918 -451 +Curve -3263 -381 -2796 -264 +Curve -2795 -264 -2793 -263 +Curve -2623 -221 -2346 -172 +<-------EndPath +Path 0 -1 -1 -2346 -172 +Curve -2345 -172 -2343 -172 +Curve -2033 -107 -2095 -52 +<-------EndPath +Path 0 1 -1 -2095 -52 +Curve -2003 -6 -1910 40 +Curve -1932 50 -1953 60 +Curve -2279 203 -2692 237 +Curve -2788 245 -2830 300 +Curve -2424 429 -2012 571 +Curve -2013 575 -2014 578 +<-------EndPath +Path 0 -1 -1 -2014 578 +Curve -1868 624 -1725 678 +Curve -1582 731 -1442 792 +<-------EndPath +Path 0 1 -1 -1442 792 +Curve -1439 784 -1436 775 +Curve -1436 775 -1435 775 +Curve -1277 833 -1150 920 +Curve -1320 959 -1490 998 +Curve -1331 1027 -1171 1056 +Curve -750 1124 -305 1162 +Curve -97 1176 111 1190 +Curve 802 1231 1492 1271 +Curve 1522 1272 1552 1272 +Curve 1745 1262 1737 1081 +Curve 1728 896 1863 797 +Curve 1866 795 1869 793 +Curve 1964 726 2129 700 +Curve 1693 627 1309 386 +Curve 1307 384 1304 382 +Curve 1189 310 1079 222 +Curve 919 96 1073 -4 +Curve 1129 -40 1209 -40 +Curve 1347 -41 1484 -41 +Curve 1514 -41 1543 -41 +Curve 1816 -41 2089 -40 +Curve 1931 -111 1820 -229 +<-------EndPath +Path 0 -1 -1 1820 -229 +Curve 1818 -230 1815 -231 +Curve 1771 -275 1756 -308 +<-------EndPath +Path 2 0 -1 -221 -1046 +Curve -188 -987 -196 -959 +Curve -303 -930 -410 -901 +Curve -545 -872 -680 -843 +Curve -886 -802 -1204 -752 +Curve -1523 -703 -1285 -643 +Curve -1047 -584 -1061 -566 +Curve -1075 -549 -1126 -544 +Curve -1137 -543 -1148 -541 +Curve -1444 -508 -1716 -408 +Curve -1742 -399 -1768 -389 +Curve -1835 -363 -2400 -353 +Curve -1678 -237 -1465 -83 +Curve -1380 -21 -1777 49 +Curve -1513 71 -1677 167 +Curve -1810 200 -1877 235 +Curve -2172 383 -1252 558 +Curve -416 717 420 875 +Curve 960 977 1356 950 +Curve 1371 949 1386 947 +Curve 1466 940 1352 832 +Curve 1164 652 948 508 +Curve 945 506 941 504 +Curve 939 503 937 501 +Curve 778 394 618 286 +Curve 508 209 663 101 +Curve 818 -8 576 -109 +Curve 334 -211 1566 -206 +Curve 768 -367 698 -456 +Curve 628 -545 698 -588 +Curve 768 -631 1737 -608 +Curve 792 -845 459 -915 +Curve 451 -917 443 -918 +Curve 423 -922 407 -929 +Curve 347 -954 339 -1022 +Curve 293 -1044 248 -1056 +Curve 215 -1062 181 -1068 +Curve 81 -1078 -13 -1038 +Curve -117 -1042 -221 -1046 +<-------EndPath +Path 3 2 -1 327 -831 +Curve 326 -832 325 -832 +Curve 3 -847 -320 -861 +Curve 174 -629 494 -672 +Curve 465 -783 374 -825 +Curve 351 -828 327 -831 +<-------EndPath +Path 3 2 -1 72 -651 +Curve -134 -664 -339 -676 +Curve -360 -677 -380 -678 +Curve -570 -688 -764 -653 +Curve -937 -621 -1045 -545 +Curve -1101 -506 -1139 -455 +Curve -1052 -340 -1256 -311 +Curve -1563 -266 -1410 -159 +Curve -1322 -98 -1178 -28 +Curve -1035 41 -1084 285 +Curve -1133 528 -704 444 +Curve -275 360 -222 364 +Curve 617 398 117 132 +Curve -383 -134 -148 -197 +Curve 87 -260 207 -308 +Curve 326 -356 -240 -516 +Curve -181 -545 -177 -565 +Curve -193 -641 72 -651 +<-------EndPath +Path 1 -1 -1 -1442 792 +Curve -1369 825 -1296 858 +Curve -3128 1002 -597 1231 +Curve -455 1244 -313 1256 +Curve -313 1256 -312 1256 +Curve 930 1360 1495 1326 +Curve 1497 1326 1498 1326 +Curve 1506 1326 1513 1325 +Curve 1535 1324 1556 1322 +Curve 1952 1291 1965 1182 +Curve 1750 1034 1857 876 +Curve 1873 853 1897 839 +Curve 1921 824 1954 819 +Curve 2067 799 2152 760 +Curve 2154 759 2155 758 +Curve 2156 758 2156 758 +Curve 2159 757 2161 756 +Curve 2194 737 2227 717 +Curve 2750 595 2170 492 +Curve 1590 388 1384 261 +Curve 1177 133 1351 85 +Curve 1400 71 1484 69 +Curve 1514 70 1543 70 +Curve 1733 74 2061 126 +Curve 2098 132 2135 138 +Curve 2744 240 2450 23 +Curve 2286 -47 2121 -117 +Curve 2121 -117 2120 -117 +Curve 1938 -191 1820 -229 +<-------EndPath +Path 1 -1 -1 -2095 -52 +Curve -2145 -10 -2427 27 +Curve -2627 52 -2744 92 +Curve -3005 179 -2865 336 +Curve -2820 362 -2774 387 +Curve -2383 460 -2014 578 +<-------EndPath +Path 3 2 -1 904 665 +Curve 882 647 860 628 +Curve 785 579 655 573 +Curve -140 417 -98 600 +Curve 425 659 725 757 +Curve 1024 854 899 787 +Curve 773 719 821 701 +Curve 863 683 904 665 +<-------EndPath +!======EndShape +=======BeginShape +Path 8 -1 0 1430 206 +Curve 1424 200 1417 193 +Curve 1287 69 1071 90 +Curve 1112 65 1093 -21 +Curve 980 -90 909 -81 +Curve 943 -133 904 -183 +Curve 861 -238 822 -211 +Curve 901 -289 825 -368 +Curve 730 -466 589 -455 +Curve 638 -488 629 -546 +Curve 601 -725 411 -722 +Curve 208 -719 141 -602 +Curve 148 -787 -35 -732 +Curve -188 -687 -250 -556 +Curve -306 -552 -337 -511 +Curve -358 -482 -364 -447 +<-------EndPath +Path 8 7 0 -364 -447 +Curve -365 -440 -366 -432 +<-------EndPath +Path 8 7 -1 -366 -432 +Curve -359 -431 -351 -430 +Curve -350 -433 -348 -435 +Curve -312 -494 -235 -513 +Curve -153 -533 -86 -484 +Curve -67 -467 -48 -450 +Curve -46 -486 -44 -522 +Curve -35 -581 24 -582 +Curve 79 -583 110 -553 +Curve 140 -523 146 -462 +Curve 187 -506 254 -530 +Curve 340 -561 428 -529 +Curve 492 -505 489 -450 +Curve 485 -431 480 -411 +Curve 462 -371 443 -330 +Curve 445 -332 447 -333 +Curve 458 -319 469 -304 +<-------EndPath +Path 8 7 0 469 -304 +Curve 549 -326 588 -246 +Curve 616 -186 560 -147 +Curve 650 -142 725 -86 +Curve 744 -69 762 -51 +<-------EndPath +Path 8 7 -1 762 -51 +Curve 766 -55 770 -59 +Curve 809 -58 847 -56 +Curve 864 -50 877 -40 +Curve 896 -25 904 1 +Curve 920 50 905 88 +Curve 899 101 892 113 +Curve 915 109 937 104 +Curve 997 101 1040 141 +Curve 1110 208 1077 304 +Curve 1117 268 1184 233 +Curve 1249 198 1319 190 +Curve 1364 184 1380 220 +Curve 1392 214 1403 207 +Curve 1411 205 1418 203 +Curve 1424 205 1430 206 +<-------EndPath +Path -1 7 -1 1430 206 +Curve 1431 206 1431 206 +<-------EndPath +Path -1 7 0 1431 206 +Curve 1436 212 1441 217 +Curve 1478 258 1507 312 +<-------EndPath +Path -1 3 0 1507 312 +Curve 1541 375 1475 407 +Curve 1475 408 1474 408 +<-------EndPath +Path -1 7 0 1474 408 +Curve 1507 425 1522 465 +Curve 1526 481 1529 497 +Curve 1541 583 1483 602 +Curve 1398 629 1363 573 +Curve 1350 591 1337 608 +Curve 1252 690 1144 656 +Curve 1109 645 1086 624 +<-------EndPath +Path -1 2 0 1086 624 +Curve 1081 627 1069 640 +Curve 1042 669 1007 688 +Curve 977 704 946 719 +Curve 910 737 872 740 +Curve 836 743 800 745 +Curve 760 750 725 736 +Curve 722 752 719 767 +Curve 712 773 705 778 +Curve 690 776 674 774 +Curve 647 771 619 774 +Curve 604 775 588 775 +Curve 575 773 562 770 +Curve 556 767 557 761 +Curve 503 704 450 626 +<-------EndPath +Path -1 5 0 450 626 +Curve 381 682 264 684 +Curve 67 688 -4 537 +Curve -26 599 -121 625 +Curve -145 631 -169 636 +<-------EndPath +Path -1 2 0 -169 636 +Curve -189 652 -208 668 +Curve -234 691 -226 709 +Curve -243 707 -259 705 +Curve -333 708 -406 710 +<-------EndPath +Path -1 1 0 -406 710 +Curve -442 670 -471 618 +<-------EndPath +Path -1 5 0 -471 618 +Curve -643 628 -836 591 +Curve -902 578 -908 517 +Curve -918 418 -865 364 +<-------EndPath +Path -1 -1 0 -865 364 +Curve -886 369 -906 406 +<-------EndPath +Path 7 8 -1 -319 -278 +Curve -319 -282 -319 -286 +Curve -317 -321 -303 -348 +Curve -286 -378 -254 -398 +Curve -224 -397 -193 -395 +Curve -155 -362 -163 -306 +Curve -137 -355 -60 -352 +Curve 59 -347 76 -238 +Curve 81 -210 94 -198 +Curve 212 -191 184 -92 +Curve 167 -33 122 8 +Curve 113 17 100 17 +Curve 88 -26 76 -68 +Curve 61 -115 21 -131 +Curve -1 -132 -23 -132 +Curve -42 -125 -56 -145 +Curve -69 -161 -92 -160 +Curve -124 -160 -148 -139 +Curve -121 -168 -153 -212 +Curve -166 -229 -183 -235 +Curve -203 -237 -223 -238 +Curve -202 -256 -243 -299 +Curve -268 -326 -316 -280 +Curve -317 -280 -317 -279 +<-------EndPath +Path 7 0 -1 -317 -279 +Curve -318 -279 -318 -278 +Curve -319 -278 -319 -278 +<-------EndPath +Path 7 7 0 -319 -278 +Curve -384 -233 -330 -154 +Curve -293 -101 -230 -103 +Curve -271 -53 -289 17 +Curve -327 162 -198 202 +Curve -151 200 -104 198 +Curve -98 196 -92 194 +Curve -27 164 3 105 +<-------EndPath +Path 7 7 0 762 -51 +Curve 762 -51 762 -50 +Curve 794 -12 804 38 +Curve 817 102 756 135 +Curve 684 175 602 158 +Curve 585 156 568 153 +<-------EndPath +Path 7 3 -1 1474 408 +Curve 1491 360 1507 312 +<-------EndPath +Path 7 7 0 1474 408 +Curve 1347 460 1291 404 +<-------EndPath +Path 7 2 0 829 448 +Curve 850 435 870 422 +Curve 849 453 845 485 +<-------EndPath +Path 7 6 0 845 485 +Curve 838 535 873 588 +Curve 1013 558 1050 488 +Curve 1042 548 1061 589 +<-------EndPath +Path 7 2 0 1061 589 +Curve 1070 609 1086 624 +<-------EndPath +Path 6 2 0 845 485 +Curve 821 518 797 551 +Curve 776 577 755 602 +Curve 733 628 710 654 +Curve 699 670 687 685 +Curve 700 686 712 687 +Curve 734 691 756 695 +Curve 789 698 822 701 +Curve 846 700 870 699 +Curve 951 689 1018 639 +Curve 1036 620 1053 600 +Curve 1057 595 1061 589 +<-------EndPath +Path 7 7 0 1363 573 +Curve 1349 552 1343 519 +<-------EndPath +Path 5 7 -1 544 449 +Curve 541 451 537 453 +Curve 512 464 487 475 +Curve 455 481 423 486 +Curve 396 487 376 470 +Curve 361 457 353 438 +Curve 342 414 350 390 +Curve 359 364 345 344 +Curve 322 359 296 370 +Curve 259 384 222 397 +Curve 179 405 136 412 +Curve 95 414 56 400 +Curve 14 384 -20 355 +Curve -54 327 -40 284 +Curve -74 317 -107 349 +Curve -161 394 -223 426 +Curve -236 433 -248 439 +Curve -294 460 -342 473 +Curve -411 493 -483 493 +Curve -553 493 -622 492 +Curve -694 491 -756 459 +Curve -834 417 -802 344 +Curve -806 336 -809 327 +<-------EndPath +Path 5 -1 0 -809 327 +Curve -843 341 -865 364 +<-------EndPath +Path 6 7 0 586 436 +Curve 582 427 577 417 +Curve 574 403 570 388 +<-------EndPath +Path 6 -1 0 570 388 +Curve 567 388 563 388 +<-------EndPath +Path 6 7 0 563 388 +Curve 552 417 544 449 +<-------EndPath +Path 6 5 0 544 449 +Curve 544 451 543 452 +<-------EndPath +Path 6 2 0 543 452 +Curve 560 488 564 529 +Curve 566 561 588 582 +Curve 597 559 597 529 +Curve 594 493 590 456 +Curve 588 446 586 436 +<-------EndPath +Path 7 2 0 586 436 +Curve 594 445 601 454 +Curve 627 479 674 482 +<-------EndPath +Path 7 6 0 674 482 +Curve 689 482 703 481 +Curve 773 475 829 448 +<-------EndPath +Path 2 6 0 829 448 +Curve 749 521 672 622 +Curve 663 634 654 646 +Curve 687 570 674 482 +<-------EndPath +Path -1 7 0 570 388 +Curve 569 381 568 373 +Curve 566 381 563 388 +<-------EndPath +Path 5 2 0 527 513 +Curve 533 493 538 473 +Curve 541 463 543 452 +<-------EndPath +Path 6 2 0 500 569 +Curve 518 624 547 656 +Curve 555 565 527 513 +<-------EndPath +Path 6 5 0 527 513 +Curve 514 541 500 569 +<-------EndPath +Path 2 5 0 500 569 +Curve 479 602 450 626 +<-------EndPath +Path 2 2 0 601 454 +Curve 634 536 605 622 +<-------EndPath +Path 8 7 0 -630 39 +Curve -642 -18 -653 -74 +Curve -654 -82 -655 -90 +<-------EndPath +Path 8 -1 0 -655 -90 +Curve -960 -158 -909 16 +Curve -846 37 -815 37 +Curve -942 69 -949 206 +Curve -952 255 -899 269 +Curve -837 287 -774 304 +<-------EndPath +Path 8 7 -1 -774 304 +Curve -788 294 -801 284 +Curve -847 247 -813 189 +Curve -791 151 -746 144 +Curve -759 139 -772 133 +Curve -813 104 -784 75 +Curve -771 65 -757 54 +Curve -693 16 -630 39 +<-------EndPath +Path 7 7 0 -630 39 +Curve -594 179 -533 268 +<-------EndPath +Path -1 7 0 -655 -90 +Curve -685 -300 -552 -433 +Curve -510 -475 -449 -475 +Curve -383 -476 -364 -447 +<-------EndPath +Path 7 7 0 -365 -382 +Curve -366 -407 -366 -431 +Curve -366 -432 -366 -432 +<-------EndPath +Path 0 8 0 -317 -279 +Curve -318 -279 -319 -278 +<-------EndPath +Path 7 -1 0 -774 304 +Curve -764 307 -753 310 +Curve -781 319 -809 327 +<-------EndPath +Path 2 1 -1 -412 676 +Curve -409 693 -406 710 +<-------EndPath +Path 1 1 0 -438 629 +Curve -425 653 -412 676 +<-------EndPath +Path 1 2 0 -412 676 +Curve -401 651 -398 611 +<-------EndPath +Path 1 5 0 -398 611 +Curve -435 615 -471 618 +<-------EndPath +Path 5 5 0 -19 498 +Curve -12 518 -4 537 +<-------EndPath +Path 5 2 0 -219 557 +Curve -229 577 -238 596 +<-------EndPath +Path 5 1 0 -238 596 +Curve -247 626 -225 635 +<-------EndPath +Path 5 2 0 -225 635 +Curve -197 636 -169 636 +<-------EndPath +Path 5 5 0 -219 557 +Curve -210 548 -208 540 +<-------EndPath +Path 5 2 0 -296 594 +Curve -280 590 -264 586 +Curve -242 572 -219 557 +<-------EndPath +Path 5 2 0 -398 611 +Curve -382 609 -365 607 +<-------EndPath +Path 5 4 0 -365 607 +Curve -331 601 -296 594 +<-------EndPath +Path 2 4 0 -296 594 +Curve -301 605 -305 615 +Curve -376 697 -365 607 +<-------EndPath +Path 1 2 0 -238 596 +Curve -284 643 -306 674 +Curve -266 655 -225 635 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 0 0 -885 -3357 +Curve -885 -3358 -885 -3358 +Curve -814 -3706 -502 -3880 +Curve -305 -3990 -110 -3972 +Curve -47 -4346 312 -4434 +Curve 720 -4535 968 -4267 +Curve 1180 -4040 1153 -3624 +<-------EndPath +Path -1 -1 0 1153 -3624 +Curve 1148 -3539 1128 -3458 +<-------EndPath +Path -1 0 0 1128 -3458 +Curve 1514 -3377 1614 -2966 +Curve 1710 -2573 1589 -2299 +Curve 1582 -2284 1574 -2268 +Curve 1521 -2164 1451 -2062 +Curve 1451 -2062 1450 -2061 +Curve 1446 -2056 1442 -2050 +<-------EndPath +Path -1 1 0 1442 -2050 +Curve 1524 -1893 1543 -1683 +<-------EndPath +Path -1 1 -1 1543 -1683 +Curve 1546 -1679 1549 -1675 +<-------EndPath +Path -1 0 0 1549 -1675 +Curve 1635 -1744 1737 -1800 +Curve 1745 -1805 1753 -1809 +Curve 1755 -1810 1757 -1811 +Curve 1766 -1816 1775 -1821 +Curve 2096 -1988 2434 -1872 +Curve 3039 -1665 2846 -1036 +Curve 2712 -597 2344 -463 +Curve 2455 -471 2507 -409 +Curve 2693 -185 2571 60 +Curve 2571 61 2570 61 +<-------EndPath +Path -1 1 0 2570 61 +Curve 2570 62 2570 62 +Curve 2526 148 2444 237 +<-------EndPath +Path -1 1 -1 2444 237 +Curve 2443 241 2442 244 +<-------EndPath +Path -1 1 0 2442 244 +Curve 2562 294 2620 401 +Curve 2819 769 2406 1019 +Curve 2134 1184 1884 1157 +Curve 1897 1361 1754 1476 +<-------EndPath +Path -1 6 0 1754 1476 +Curve 1649 1559 1460 1594 +Curve 1233 1637 1029 1601 +Curve 869 1573 724 1497 +<-------EndPath +Path -1 6 -1 724 1497 +Curve 714 1497 704 1497 +<-------EndPath +Path -1 6 0 704 1497 +Curve 341 1441 544 1195 +Curve 80 1166 249 710 +<-------EndPath +Path -1 3 0 249 710 +Curve 176 731 103 752 +Curve 75 762 46 772 +Curve -1 789 -42 814 +Curve -44 816 -46 817 +Curve -241 935 -322 1203 +Curve -406 1486 -391 1777 +Curve -387 1826 -383 1874 +Curve -377 1923 -370 1971 +Curve -338 2174 -306 2376 +<-------EndPath +Path -1 8 0 -306 2376 +Curve -305 2382 -304 2387 +<-------EndPath +Path -1 3 0 -304 2387 +Curve -291 2475 -278 2562 +Curve -276 2582 -273 2602 +Curve -265 2662 -256 2722 +Curve -204 3098 -222 3539 +Curve -232 3785 -163 3960 +Curve -108 4099 -4 4194 +Curve 160 4342 226 4375 +<-------EndPath +Path -1 -1 0 226 4375 +Curve 281 4368 264 4382 +Curve 254 4389 226 4375 +<-------EndPath +Path -1 3 0 226 4375 +Curve 194 4380 161 4385 +<-------EndPath +Path -1 -1 0 161 4385 +Curve 173 4391 184 4397 +<-------EndPath +Path 0 0 0 -115 -3943 +Curve -113 -3958 -110 -3972 +Curve -12 -3964 85 -3923 +<-------EndPath +Path -1 1 0 -895 -3303 +Curve -890 -3330 -885 -3357 +<-------EndPath +Path 0 1 -1 -885 -3357 +Curve -662 -3766 -150 -3797 +Curve -48 -3791 54 -3785 +Curve 142 -3766 205 -3723 +Curve 221 -3795 242 -3854 +Curve 385 -4251 729 -4024 +Curve 1035 -3822 1024 -3464 +Curve 1021 -3388 1005 -3306 +Curve 967 -3114 903 -2980 +Curve 916 -2968 928 -2955 +Curve 1305 -3343 1440 -2907 +Curve 1450 -2872 1459 -2837 +Curve 1516 -2595 1473 -2350 +Curve 1445 -2191 1416 -2085 +<-------EndPath +Path 0 4 0 1416 -2085 +Curve 1429 -2068 1442 -2050 +<-------EndPath +Path 1 4 0 1442 -2050 +Curve 1403 -1998 1363 -1946 +Curve 1363 -1945 1362 -1944 +<-------EndPath +Path 1 1 0 1362 -1944 +Curve 1353 -1934 1344 -1923 +<-------EndPath +Path 1 -1 -1 -895 -3303 +Curve -912 -3282 -928 -3260 +<-------EndPath +Path 1 0 0 -928 -3260 +Curve -920 -3253 -912 -3246 +Curve -638 -3010 -708 -2589 +Curve -764 -2254 -913 -1976 +<-------EndPath +Path 1 1 0 -913 -1976 +Curve -926 -1936 -938 -1896 +<-------EndPath +Path 1 1 0 201 -3707 +Curve 203 -3715 205 -3723 +<-------EndPath +Path 1 1 0 -123 -3372 +Curve -126 -3379 -128 -3385 +Curve -132 -3394 -135 -3403 +<-------EndPath +Path 1 2 0 165 -1863 +Curve 192 -1952 211 -2042 +Curve 248 -2220 253 -2405 +Curve 252 -2503 250 -2601 +Curve 242 -2735 198 -2851 +Curve 146 -2989 44 -3102 +Curve 41 -3106 37 -3109 +Curve -64 -3224 -123 -3372 +Curve -12 -3264 99 -3155 +Curve 100 -3155 100 -3154 +Curve 216 -3032 331 -2893 +Curve 365 -3013 399 -3133 +Curve 490 -3465 507 -3597 +Curve 529 -3774 539 -3733 +Curve 572 -3406 527 -3097 +Curve 473 -2731 401 -2395 +Curve 362 -2210 328 -2022 +Curve 299 -1842 269 -1662 +Curve 268 -1653 266 -1643 +<-------EndPath +Path 1 2 -1 266 -1643 +Curve 255 -1638 244 -1632 +<-------EndPath +Path 1 0 0 244 -1632 +Curve 245 -1631 245 -1630 +Curve 255 -1612 265 -1593 +<-------EndPath +Path 1 0 -1 265 -1593 +Curve 269 -1594 272 -1594 +<-------EndPath +Path 1 1 0 272 -1594 +Curve 272 -1595 272 -1595 +Curve 268 -1609 264 -1623 +<-------EndPath +Path -1 0 0 -2118 -782 +Curve -2525 -742 -2752 -1085 +Curve -2969 -1415 -2851 -1816 +Curve -2741 -2190 -2462 -2362 +Curve -2404 -2398 -2340 -2416 +Curve -2394 -2775 -2181 -3052 +Curve -1943 -3362 -1591 -3416 +Curve -1195 -3478 -928 -3260 +<-------EndPath +Path 2 1 0 -1771 -1919 +Curve -1791 -2124 -1783 -2341 +Curve -1781 -2422 -1770 -2500 +<-------EndPath +Path 2 1 -1 -1770 -2500 +Curve -1776 -2501 -1782 -2502 +<-------EndPath +Path 2 1 0 -1782 -2502 +Curve -1814 -2415 -1827 -2322 +Curve -1841 -2229 -1836 -2129 +Curve -1833 -2024 -1830 -1919 +<-------EndPath +Path 2 3 -1 -1830 -1919 +Curve -1801 -1919 -1771 -1919 +<-------EndPath +Path 1 3 0 -1771 -1919 +Curve -1771 -1918 -1771 -1916 +Curve -1750 -1707 -1709 -1503 +Curve -1698 -1458 -1687 -1412 +Curve -1649 -1270 -1582 -1136 +Curve -1537 -1046 -1484 -966 +Curve -1484 -966 -1483 -965 +Curve -1431 -885 -1370 -815 +<-------EndPath +Path 1 3 -1 -1370 -815 +Curve -1363 -815 -1356 -815 +<-------EndPath +Path 1 3 0 -1356 -815 +Curve -1061 -598 -836 -315 +Curve -796 -261 -756 -206 +Curve -755 -205 -754 -204 +Curve -754 -204 -754 -203 +Curve -671 -80 -610 51 +Curve -610 52 -610 52 +Curve -549 184 -511 324 +Curve -457 526 -388 615 +<-------EndPath +Path 1 6 -1 -388 615 +Curve -103 209 -419 27 +Curve -420 27 -420 26 +Curve -448 12 -476 -3 +Curve -482 -8 -487 -12 +Curve -453 -51 -419 -90 +Curve -393 -123 -367 -156 +Curve -146 -445 -376 -783 +Curve -369 -795 -361 -807 +<-------EndPath +Path 1 1 0 -361 -807 +Curve -362 -808 -363 -808 +Curve -370 -812 -376 -815 +<-------EndPath +Path 3 1 0 -1830 -1919 +Curve -1830 -1918 -1830 -1916 +Curve -1830 -1826 -1830 -1735 +Curve -1833 -1547 -1786 -1388 +<-------EndPath +Path 3 1 -1 -1786 -1388 +Curve -1790 -1388 -1793 -1387 +<-------EndPath +Path 3 1 0 -1793 -1387 +Curve -1805 -1393 -1817 -1399 +Curve -1992 -1493 -2074 -1660 +Curve -2123 -1758 -2148 -1839 +<-------EndPath +Path 3 1 -1 -2148 -1839 +Curve -2155 -1837 -2161 -1835 +<-------EndPath +Path 3 1 0 -2161 -1835 +Curve -2142 -1613 -2019 -1460 +Curve -1964 -1393 -1908 -1325 +Curve -1908 -1325 -1907 -1324 +Curve -1894 -1308 -1880 -1291 +Curve -1832 -1235 -1784 -1179 +Curve -1732 -1117 -1680 -1054 +Curve -1625 -979 -1570 -903 +Curve -1569 -902 -1568 -900 +Curve -1542 -862 -1524 -821 +Curve -1524 -821 -1523 -820 +Curve -1522 -818 -1521 -815 +<-------EndPath +Path 3 5 0 -1521 -815 +Curve -1516 -803 -1511 -791 +<-------EndPath +Path 3 1 0 -1511 -791 +Curve -1506 -786 -1501 -781 +Curve -1481 -759 -1461 -736 +Curve -1459 -733 -1457 -730 +Curve -1457 -729 -1456 -728 +Curve -1454 -725 -1451 -722 +Curve -1269 -493 -1086 -263 +Curve -1062 -234 -1038 -204 +Curve -874 -2 -815 282 +Curve -796 376 -788 480 +Curve -769 716 -750 952 +Curve -738 1089 -726 1226 +Curve -725 1241 -723 1256 +<-------EndPath +Path 3 6 0 -723 1256 +Curve -716 1339 -708 1422 +<-------EndPath +Path 3 -1 0 -708 1422 +Curve -699 1523 -689 1624 +Curve -681 1714 -673 1803 +Curve -664 1903 -654 2003 +Curve -654 2006 -653 2008 +Curve -639 2161 -635 2315 +Curve -632 2465 -639 2615 +Curve -645 2702 -651 2789 +Curve -684 3169 -717 3446 +Curve -724 3482 -731 3517 +Curve -801 3771 -1156 4108 +Curve -1561 4492 -1116 4205 +<-------EndPath +Path 3 3 0 -1116 4205 +Curve -1166 4225 -1176 4225 +<-------EndPath +Path 0 0 0 -2340 -2416 +Curve -2328 -2420 -2315 -2423 +<-------EndPath +Path 0 0 0 -2335 -2383 +Curve -2338 -2400 -2340 -2416 +<-------EndPath +Path 1 0 0 -2017 -2352 +Curve -2017 -2352 -2017 -2351 +<-------EndPath +Path 1 0 -1 -2017 -2351 +Curve -2025 -2352 -2032 -2353 +Curve -2161 -2325 -2261 -2265 +Curve -2500 -2122 -2570 -1798 +Curve -2676 -1304 -2367 -1037 +Curve -2238 -918 -2108 -798 +<-------EndPath +Path 1 1 0 -2108 -798 +Curve -2102 -807 -2096 -815 +<-------EndPath +Path 0 1 -1 -191 -2108 +Curve -195 -2110 -199 -2111 +<-------EndPath +Path 0 1 0 -199 -2111 +Curve -512 -2137 -556 -1863 +<-------EndPath +Path 0 1 -1 -556 -1863 +Curve -221 -2050 14 -1759 +Curve 96 -1658 164 -1533 +Curve 240 -1392 298 -1221 +<-------EndPath +Path 0 1 0 298 -1221 +Curve 317 -1422 272 -1594 +<-------EndPath +Path 2 0 0 143 -1855 +Curve 144 -1854 144 -1853 +Curve 145 -1852 145 -1850 +Curve 152 -1834 158 -1817 +Curve 176 -1776 194 -1734 +Curve 218 -1684 242 -1634 +Curve 243 -1633 244 -1632 +<-------EndPath +Path 1 1 0 144 -1883 +Curve 135 -1893 126 -1903 +<-------EndPath +Path 1 0 0 126 -1903 +Curve 135 -1879 143 -1855 +<-------EndPath +Path 1 2 -1 143 -1855 +Curve 154 -1859 165 -1863 +<-------EndPath +Path 0 1 0 126 -1903 +Curve -6 -2047 -191 -2108 +<-------EndPath +Path 1 0 -1 -913 -1976 +Curve -811 -2333 -867 -2550 +Curve -960 -2912 -1493 -2884 +Curve -1964 -2859 -2017 -2352 +<-------EndPath +Path 1 1 0 -913 -1976 +Curve -934 -1940 -955 -1903 +<-------EndPath +Path 1 1 0 298 -1221 +Curve 298 -1213 297 -1204 +Curve 296 -1194 294 -1184 +<-------EndPath +Path 0 1 0 1174 -1454 +Curve 1114 -1636 840 -1658 +Curve 651 -1673 563 -1524 +Curve 554 -1508 545 -1492 +Curve 534 -1473 523 -1453 +Curve 480 -1375 445 -1293 +Curve 424 -1238 402 -1182 +Curve 400 -1176 397 -1169 +Curve 349 -1033 320 -888 +Curve 312 -848 312 -812 +Curve 312 -811 312 -810 +<-------EndPath +Path 0 1 -1 312 -810 +Curve 315 -788 317 -766 +<-------EndPath +Path 0 0 0 317 -766 +Curve 318 -759 319 -752 +<-------EndPath +Path 0 -1 -1 319 -752 +Curve 331 -721 342 -689 +<-------EndPath +Path 0 1 -1 342 -689 +Curve 342 -689 342 -688 +Curve 343 -693 344 -698 +Curve 402 -1009 556 -1246 +Curve 850 -1699 1174 -1454 +<-------EndPath +Path 1 1 0 1174 -1454 +Curve 1175 -1452 1175 -1449 +Curve 1202 -1362 1181 -1238 +Curve 1181 -1238 1181 -1237 +Curve 1176 -1214 1171 -1191 +Curve 1170 -1187 1169 -1183 +Curve 1167 -1173 1164 -1163 +<-------EndPath +Path 0 -1 -1 1121 -3460 +Curve 1137 -3542 1153 -3624 +<-------EndPath +Path 0 0 0 1128 -3458 +Curve 1117 -3421 1105 -3383 +<-------EndPath +Path -1 0 0 1121 -3460 +Curve 1125 -3459 1128 -3458 +<-------EndPath +Path 0 0 0 1105 -3463 +Curve 1113 -3462 1121 -3460 +<-------EndPath +Path 4 1 0 1363 -1946 +Curve 1363 -1946 1362 -1945 +Curve 1362 -1945 1362 -1944 +<-------EndPath +Path 4 1 0 1416 -2085 +Curve 1390 -1997 1363 -1946 +<-------EndPath +Path 0 1 0 1549 -1675 +Curve 1549 -1675 1549 -1674 +Curve 1405 -1559 1305 -1409 +Curve 1237 -1308 1217 -1230 +Curve 1210 -1205 1209 -1181 +<-------EndPath +Path 0 1 -1 1209 -1181 +Curve 1415 -1539 1808 -1681 +Curve 1816 -1684 1824 -1687 +Curve 1841 -1693 1857 -1698 +Curve 2336 -1851 2547 -1443 +Curve 2651 -1243 2573 -1063 +Curve 2445 -764 2249 -556 +Curve 2199 -467 2148 -378 +Curve 2600 -320 2559 55 +Curve 2565 58 2570 61 +<-------EndPath +Path 1 1 0 2442 244 +Curve 2433 241 2424 237 +<-------EndPath +Path 1 3 -1 1838 -15 +Curve 1840 -12 1842 -9 +<-------EndPath +Path 1 3 0 1842 -9 +Curve 1748 130 1576 225 +Curve 1535 248 1493 271 +Curve 1493 271 1492 271 +Curve 1366 337 1240 402 +<-------EndPath +Path 1 2 -1 1240 402 +Curve 1241 405 1242 407 +<-------EndPath +Path 1 3 0 1242 407 +Curve 1276 459 1337 477 +Curve 1517 531 1690 648 +Curve 1620 644 1501 608 +Curve 1340 560 1196 474 +Curve 1196 474 1195 473 +Curve 1161 452 1127 430 +Curve 1093 439 1059 447 +Curve 1010 459 960 471 +Curve 934 479 907 487 +Curve 803 519 704 567 +Curve 704 569 704 571 +Curve 564 615 424 658 +<-------EndPath +Path 1 6 -1 424 658 +Curve 270 1130 723 1127 +<-------EndPath +Path 1 1 0 723 1127 +Curve 724 1122 724 1117 +<-------EndPath +Path 1 1 0 1696 -496 +Curve 1701 -497 1705 -498 +Curve 1715 -501 1724 -503 +<-------EndPath +Path 1 3 0 704 -426 +Curve 705 -427 706 -427 +Curve 751 -436 795 -444 +Curve 960 -481 1106 -542 +Curve 1231 -594 1343 -665 +Curve 1441 -725 1539 -784 +Curve 1338 -606 1124 -502 +Curve 1125 -502 1125 -501 +Curve 1139 -457 1165 -429 +Curve 1203 -388 1266 -383 +Curve 1329 -378 1416 -411 +Curve 1561 -464 1696 -496 +Curve 1498 -338 1268 -335 +Curve 1176 -335 1078 -359 +Curve 967 -386 820 -344 +Curve 815 -343 810 -342 +Curve 757 -325 704 -308 +<-------EndPath +Path 1 4 0 704 -308 +Curve 683 -300 661 -292 +<-------EndPath +Path 1 3 0 661 -292 +Curve 611 -265 572 -227 +Curve 490 -150 449 -34 +Curve 449 -33 448 -31 +Curve 437 8 426 47 +Curve 422 72 417 96 +<-------EndPath +Path 1 6 -1 417 96 +Curve 461 458 877 428 +<-------EndPath +Path 1 3 0 877 428 +Curve 883 426 888 424 +Curve 889 424 890 424 +Curve 978 395 1062 358 +Curve 1129 329 1195 300 +Curve 1322 244 1449 188 +Curve 1553 143 1656 97 +Curve 1758 43 1838 -15 +<-------EndPath +Path 1 1 0 1838 -15 +Curve 1846 -21 1853 -27 +<-------EndPath +Path 5 1 0 704 -426 +Curve 704 -431 704 -436 +Curve 693 -433 682 -429 +<-------EndPath +Path 5 3 0 682 -429 +Curve 693 -428 704 -426 +<-------EndPath +Path 3 1 0 682 -429 +Curve 579 -396 496 -338 +Curve 368 -250 287 -106 +<-------EndPath +Path 3 6 0 287 -106 +Curve 261 -61 241 -11 +Curve 240 -9 239 -6 +Curve 237 -2 235 2 +Curve 226 25 217 48 +Curve 187 115 156 181 +<-------EndPath +Path 3 -1 0 156 181 +Curve 71 351 -35 493 +<-------EndPath +Path 3 7 0 -35 493 +Curve -68 534 -101 575 +Curve -134 614 -165 639 +Curve -182 651 -199 663 +Curve -251 692 -297 681 +Curve -308 678 -318 674 +Curve -327 670 -335 665 +<-------EndPath +Path 3 6 0 -335 665 +Curve -362 648 -387 616 +Curve -388 616 -388 615 +<-------EndPath +Path 3 3 0 661 -292 +Curve 623 -279 584 -252 +<-------EndPath +Path 4 3 0 704 -308 +Curve 704 -312 704 -315 +Curve 681 -305 661 -292 +<-------EndPath +Path 3 2 0 1242 407 +Curve 1235 405 1240 402 +<-------EndPath +Path 6 3 0 417 96 +Curve 406 162 405 238 +Curve 405 242 405 245 +Curve 402 631 723 472 +Curve 714 473 704 473 +<-------EndPath +Path 6 6 0 704 473 +Curve 697 475 690 476 +<-------EndPath +Path 6 3 0 704 473 +Curve 707 473 709 472 +Curve 793 450 877 428 +<-------EndPath +Path 6 1 -1 1754 1476 +Curve 1487 1560 1144 1553 +Curve 1092 1549 1039 1545 +Curve 696 1492 723 1127 +<-------EndPath +Path -1 1 0 316 -774 +Curve 316 -775 316 -775 +<-------EndPath +Path -1 1 -1 316 -775 +Curve 315 -779 314 -782 +Curve 315 -774 316 -766 +Curve 318 -753 316 -774 +<-------EndPath +Path 1 1 0 316 -774 +Curve 317 -770 317 -766 +<-------EndPath +Path 0 1 -1 317 -766 +Curve 317 -762 317 -757 +<-------EndPath +Path 0 -1 -1 317 -757 +Curve 318 -755 319 -752 +<-------EndPath +Path -1 -1 0 319 -752 +Curve 319 -752 319 -751 +<-------EndPath +Path -1 1 -1 319 -751 +Curve 324 -735 329 -718 +Curve 332 -711 335 -703 +Curve 337 -699 339 -695 +Curve 339 -695 339 -694 +Curve 341 -692 342 -689 +<-------EndPath +Path 1 1 0 316 -775 +Curve 316 -779 315 -783 +Curve 314 -793 313 -803 +Curve 313 -807 312 -810 +Curve 313 -796 314 -782 +<-------EndPath +Path 1 -1 -1 319 -751 +Curve 318 -754 317 -757 +<-------EndPath +Path 1 1 0 364 -535 +Curve 342 -584 324 -715 +Curve 324 -716 324 -717 +Curve 322 -734 319 -751 +<-------EndPath +Path 1 6 -1 364 -535 +Curve 372 -518 379 -501 +Curve 118 -406 287 -106 +<-------EndPath +Path 1 6 0 23 -363 +Curve 45 -428 85 -492 +Curve 208 -688 364 -535 +<-------EndPath +Path 4 6 0 -127 -410 +Curve -132 -397 -137 -384 +<-------EndPath +Path 4 -1 0 -137 -384 +Curve -138 -292 -94 -256 +<-------EndPath +Path 4 4 0 -94 -256 +Curve -92 -261 -89 -265 +<-------EndPath +Path 1 4 -1 -127 -410 +Curve -52 -387 23 -363 +<-------EndPath +Path 6 4 0 23 -363 +Curve 1 -299 -2 -233 +Curve -2 -233 -2 -232 +<-------EndPath +Path 6 7 0 -2 -232 +Curve -7 -148 20 -62 +Curve 31 -34 41 -5 +<-------EndPath +Path 6 -1 0 41 -5 +Curve 81 87 156 181 +<-------EndPath +Path 1 6 0 -361 -807 +Curve -332 -791 -303 -775 +Curve -60 -625 -127 -410 +<-------EndPath +Path 4 7 0 -94 -256 +Curve -61 -228 -2 -232 +<-------EndPath +Path -1 6 0 -137 -384 +Curve -164 -316 -220 -243 +Curve -300 -139 -376 -55 +Curve -285 -119 -224 -109 +Curve -197 -105 -176 -86 +<-------EndPath +Path -1 7 0 -176 -86 +Curve -131 -190 -94 -256 +<-------EndPath +Path 7 6 0 -176 -86 +Curve -148 -62 -129 -11 +Curve -108 43 -100 129 +Curve -92 210 -97 282 +Curve -115 495 -261 615 +Curve -265 618 -269 621 +Curve -302 643 -335 665 +<-------EndPath +Path 7 -1 0 -35 493 +Curve -44 386 -33 287 +Curve -27 217 -11 152 +Curve 8 70 41 -5 +<-------EndPath +Path 3 2 -1 -608 1617 +Curve -599 1217 -648 908 +Curve -698 598 -725 454 +Curve -752 310 -751 286 +Curve -752 271 -752 256 +Curve -754 247 -755 237 +Curve -822 -98 -1015 -321 +Curve -1036 -346 -1057 -370 +Curve -1126 -429 -1168 -490 +Curve -1113 -430 -1057 -370 +Curve -1032 -350 -1006 -329 +Curve -953 -290 -910 -243 +Curve -870 -199 -838 -148 +Curve -743 5 -708 107 +Curve -673 208 -686 242 +Curve -699 275 -671 366 +Curve -643 457 -597 545 +Curve -523 661 -409 710 +Curve -235 787 -93 665 +Curve 31 559 113 436 +Curve 199 309 273 143 +Curve 288 113 302 83 +Curve 279 157 276 209 +Curve 266 401 225 583 +Curve 162 631 75 663 +Curve 43 673 11 682 +Curve -77 705 -150 747 +Curve -343 858 -424 1101 +Curve -500 1328 -492 1617 +Curve -492 1623 -491 1628 +Curve -491 1630 -491 1632 +Curve -486 1708 -481 1783 +Curve -478 1810 -475 1837 +Curve -472 1860 -469 1883 +Curve -441 2135 -439 2380 +Curve -438 2480 -442 2578 +Curve -444 2651 -446 2723 +Curve -447 2749 -447 2775 +Curve -452 3064 -435 3320 +Curve -426 3456 -401 3579 +Curve -355 3812 -252 3995 +Curve -247 4004 -242 4013 +Curve -100 4252 161 4385 +<-------EndPath +Path -1 2 0 161 4385 +Curve 122 4393 83 4401 +<-------EndPath +Path -1 -1 0 83 4401 +Curve 68 4427 50 4428 +Curve 34 4428 17 4412 +<-------EndPath +Path -1 2 0 17 4412 +Curve -213 4299 -286 4355 +Curve -387 4433 -377 4462 +Curve -666 4147 -838 4363 +Curve -967 4290 -1095 4217 +<-------EndPath +Path -1 3 0 -1095 4217 +Curve -1106 4211 -1116 4205 +<-------EndPath +Path 6 1 -1 -723 1256 +Curve -730 1257 -736 1257 +Curve -1007 1278 -983 1148 +Curve -976 1126 -968 1104 +Curve -968 1104 -968 1103 +Curve -941 1044 -870 962 +Curve -1305 1043 -1410 735 +Curve -1505 454 -1376 177 +Curve -1387 170 -1397 163 +<-------EndPath +Path 6 -1 0 -1397 163 +Curve -1397 164 -1397 164 +Curve -1559 383 -1585 688 +Curve -1622 1120 -1176 1145 +Curve -1098 1149 -1054 1125 +<-------EndPath +Path 6 6 0 -1054 1125 +Curve -1043 1117 -1032 1108 +Curve -1024 1097 -1016 1085 +<-------EndPath +Path 3 6 0 249 710 +Curve 337 684 424 658 +<-------EndPath +Path 1 5 -1 -1536 -815 +Curve -1529 -815 -1521 -815 +<-------EndPath +Path 5 1 0 -1536 -815 +Curve -1524 -803 -1511 -791 +<-------EndPath +Path -1 1 0 -1397 163 +Curve -1397 163 -1396 162 +Curve -1807 106 -2053 -175 +Curve -2319 -480 -2118 -782 +<-------EndPath +Path 0 1 0 -2118 -782 +Curve -2113 -790 -2108 -798 +<-------EndPath +Path 1 1 0 -2108 -798 +Curve -2107 -797 -2106 -796 +Curve -2094 -785 -2082 -773 +<-------EndPath +Path 3 2 -1 -1095 4217 +Curve -819 4078 -712 3779 +Curve -671 3665 -640 3541 +Curve -640 3540 -640 3538 +Curve -587 3316 -568 3060 +Curve -558 2923 -557 2789 +Curve -557 2782 -557 2775 +Curve -557 2564 -579 2360 +Curve -598 2186 -605 2005 +Curve -613 1822 -608 1632 +Curve -608 1625 -608 1617 +<-------EndPath +Path -1 6 0 -708 1422 +Curve -930 1509 -1056 1353 +Curve -1149 1237 -1054 1125 +<-------EndPath +Path 3 8 -1 -304 2387 +Curve -315 2383 -325 2379 +Curve -316 2378 -306 2376 +<-------EndPath +Path -1 2 0 83 4401 +Curve 50 4407 17 4412 +<-------EndPath +!======EndShape +=======BeginShape +Path 1 0 -1 -409 -2925 +Curve -421 -2925 -433 -2924 +Curve -767 -2951 -859 -2729 +Curve -862 -2723 -864 -2716 +Curve -913 -2585 -883 -2372 +Curve -860 -2204 -799 -2086 +<-------EndPath +Path 1 1 0 -799 -2086 +Curve -790 -2089 -781 -2092 +Curve -738 -2111 -684 -2121 +<-------EndPath +Path 0 0 0 -572 -3173 +Curve -577 -3175 -582 -3177 +Curve -588 -3177 -594 -3176 +Curve -582 -3135 -563 -3101 +<-------EndPath +Path -1 0 0 -811 -2097 +Curve -1079 -2369 -1002 -2758 +Curve -999 -2774 -996 -2789 +Curve -908 -3165 -594 -3176 +Curve -600 -3197 -606 -3218 +Curve -611 -3237 -616 -3256 +Curve -655 -3642 -375 -3902 +Curve -72 -4184 324 -4136 +Curve 505 -4115 633 -3963 +Curve 857 -3699 866 -3337 +Curve 1270 -3263 1480 -2924 +Curve 1597 -2734 1592 -2557 +Curve 1592 -2554 1592 -2551 +Curve 1593 -2552 1594 -2553 +Curve 1599 -2556 1603 -2558 +Curve 1737 -2628 2030 -2535 +Curve 2322 -2443 2351 -2229 +Curve 2371 -2063 2391 -1897 +Curve 2401 -1778 2182 -1569 +Curve 2318 -1272 2098 -1030 +<-------EndPath +Path -1 5 0 2098 -1030 +Curve 1961 -879 1816 -809 +Curve 1815 -809 1814 -808 +<-------EndPath +Path -1 1 0 1814 -808 +Curve 1796 -800 1777 -792 +Curve 1769 -789 1760 -785 +Curve 1618 -734 1469 -757 +Curve 1469 -733 1469 -708 +<-------EndPath +Path -1 1 -1 1469 -708 +Curve 1472 -720 1474 -732 +<-------EndPath +Path -1 1 0 1474 -732 +Curve 1438 -426 1290 -393 +<-------EndPath +Path -1 4 0 1290 -393 +Curve 1742 -433 1511 -43 +Curve 1480 5 1448 53 +Curve 1187 411 749 431 +Curve 783 458 826 478 +Curve 1320 705 969 1011 +Curve 632 1304 262 1210 +<-------EndPath +Path -1 3 0 262 1210 +Curve 304 1567 293 1951 +Curve 290 2075 294 2197 +Curve 295 2227 296 2256 +Curve 301 2327 306 2397 +Curve 315 2501 330 2603 +Curve 339 2657 347 2711 +Curve 356 2756 364 2801 +Curve 377 2858 389 2915 +Curve 447 3173 535 3416 +Curve 560 3477 584 3538 +Curve 673 3741 934 3972 +Curve 1021 4050 1129 4131 +Curve 1070 4120 1011 4109 +<-------EndPath +Path -1 -1 0 1011 4109 +Curve 1050 4126 1089 4143 +<-------EndPath +Path 1 1 0 -409 -2925 +Curve -409 -2912 -408 -2899 +<-------EndPath +Path 1 0 -1 1473 -2366 +Curve 1472 -2432 1462 -2489 +Curve 1459 -2506 1455 -2522 +Curve 1421 -2674 1321 -2770 +Curve 1221 -2867 1056 -2908 +Curve 747 -2986 696 -2849 +Curve 687 -2981 660 -3094 +Curve 584 -3416 366 -3589 +Curve -42 -3911 -309 -3425 +Curve -369 -3315 -394 -3183 +Curve -397 -3164 -400 -3145 +Curve -404 -3115 -407 -3084 +Curve -414 -3008 -409 -2925 +<-------EndPath +Path 1 0 -1 -781 -2092 +Curve -628 -2134 -511 -2037 +Curve -825 -1996 -881 -1760 +Curve -897 -1696 -893 -1617 +Curve -898 -1616 -902 -1615 +Curve -902 -1613 -901 -1610 +Curve -937 -1684 -973 -1758 +Curve -1003 -1786 -1033 -1813 +Curve -1163 -1919 -1284 -1905 +Curve -1438 -1887 -1577 -1672 +Curve -1695 -1488 -1707 -1296 +Curve -1712 -1229 -1703 -1160 +Curve -1703 -1159 -1703 -1158 +Curve -1703 -1158 -1702 -1157 +Curve -1701 -1149 -1700 -1141 +Curve -1699 -1136 -1698 -1131 +Curve -1687 -1062 -1662 -991 +Curve -1671 -990 -1679 -989 +Curve -1687 -988 -1695 -987 +Curve -1735 -980 -1775 -973 +Curve -2068 -900 -1896 -585 +Curve -1861 -530 -1826 -474 +Curve -1823 -455 -1819 -435 +<-------EndPath +Path 1 1 0 -1819 -435 +Curve -1803 -438 -1787 -441 +<-------EndPath +Path -1 0 0 -2051 -497 +Curve -2381 -691 -2098 -1029 +Curve -2010 -1134 -1831 -1137 +Curve -1987 -1484 -1722 -1813 +Curve -1559 -2015 -1306 -2035 +Curve -1302 -2036 -1297 -2036 +Curve -1193 -2043 -1074 -2020 +Curve -995 -2004 -927 -1982 +<-------EndPath +Path -1 1 -1 -927 -1982 +Curve -914 -2036 -863 -2061 +Curve -835 -2073 -807 -2084 +Curve -809 -2091 -811 -2097 +<-------EndPath +Path 0 1 -1 -811 -2097 +Curve -805 -2092 -799 -2086 +<-------EndPath +Path 1 1 0 -799 -2086 +Curve -799 -2085 -798 -2084 +<-------EndPath +Path 1 0 0 -798 -2084 +Curve -790 -2088 -781 -2092 +<-------EndPath +Path -1 1 0 117 -1928 +Curve 116 -1937 115 -1946 +Curve 108 -1976 101 -2006 +<-------EndPath +Path -1 2 0 101 -2006 +Curve 109 -1969 117 -1931 +Curve 117 -1930 117 -1928 +<-------EndPath +Path 1 3 0 117 -1928 +Curve 166 -1700 214 -1472 +Curve 248 -1575 291 -1676 +Curve 365 -1855 438 -2033 +<-------EndPath +Path 1 2 0 438 -2033 +Curve 546 -2305 654 -2577 +Curve 518 -2143 464 -2023 +<-------EndPath +Path 1 3 0 464 -2023 +Curve 409 -1903 266 -1246 +Curve 294 -1131 322 -1015 +Curve 339 -950 356 -884 +<-------EndPath +Path 1 4 -1 356 -884 +Curve 437 -669 711 -767 +<-------EndPath +Path 1 3 0 711 -767 +Curve 740 -792 768 -817 +Curve 847 -893 925 -969 +Curve 932 -975 938 -981 +Curve 1051 -1164 1064 -1284 +Curve 1075 -1407 1086 -1529 +Curve 1096 -1653 1116 -1747 +Curve 1132 -1594 1117 -1472 +Curve 1101 -1350 1130 -1310 +Curve 1145 -1290 1160 -1270 +Curve 1186 -1266 1227 -1309 +Curve 1245 -1331 1262 -1353 +Curve 1425 -1558 1709 -1797 +Curve 1534 -1544 1344 -1292 +Curve 1344 -1292 1343 -1291 +Curve 1319 -1260 1294 -1228 +Curve 1170 -1064 1046 -900 +Curve 976 -806 905 -712 +<-------EndPath +Path 1 -1 -1 905 -712 +Curve 907 -711 909 -709 +<-------EndPath +Path 1 3 0 909 -709 +Curve 702 -467 607 -329 +Curve 577 -280 546 -231 +Curve 444 -29 377 161 +Curve 331 293 301 418 +Curve 261 587 248 759 +Curve 236 923 249 1091 +<-------EndPath +Path 1 4 -1 249 1091 +Curve 634 1232 766 855 +Curve 867 563 552 450 +Curve 631 405 711 362 +Curve 920 246 1135 135 +Curve 1277 62 1339 -20 +Curve 1442 -156 1322 -317 +Curve 1291 -354 1260 -390 +<-------EndPath +Path 1 1 0 1260 -390 +Curve 1258 -393 1255 -395 +Curve 1232 -416 1209 -437 +<-------EndPath +Path 2 3 -1 72 -1922 +Curve 95 -1925 117 -1928 +<-------EndPath +Path 2 1 0 101 -2006 +Curve 72 -2140 43 -2274 +Curve 58 -2098 72 -1922 +<-------EndPath +Path 3 1 0 72 -1922 +Curve 114 -1422 148 -1225 +Curve 154 -1194 160 -1162 +Curve 199 -990 257 -797 +Curve 258 -796 258 -795 +Curve 271 -754 283 -712 +<-------EndPath +Path 3 -1 0 283 -712 +Curve 284 -711 284 -709 +<-------EndPath +Path 3 2 0 284 -709 +Curve 299 -683 283 -684 +<-------EndPath +Path 3 1 0 283 -684 +Curve 403 -341 152 -190 +Curve -158 -4 -465 -246 +Curve -548 -312 -617 -382 +Curve -764 -531 -846 -699 +<-------EndPath +Path 3 2 0 -846 -699 +Curve -849 -704 -852 -709 +<-------EndPath +Path 3 1 0 -852 -709 +Curve -894 -1023 -881 -1357 +<-------EndPath +Path 3 1 -1 -881 -1357 +Curve -884 -1358 -886 -1358 +<-------EndPath +Path 3 1 0 -886 -1358 +Curve -887 -1358 -887 -1358 +Curve -927 -1249 -931 -1125 +Curve -936 -986 -930 -858 +Curve -926 -792 -948 -745 +Curve -957 -727 -969 -712 +<-------EndPath +Path 3 -1 -1 -969 -712 +Curve -969 -711 -969 -709 +Curve -970 -709 -971 -709 +<-------EndPath +Path 3 2 0 -971 -709 +Curve -1003 -673 -1064 -664 +Curve -1088 -661 -1111 -658 +<-------EndPath +Path 3 1 0 -1111 -658 +Curve -1204 -655 -1297 -651 +<-------EndPath +Path 3 -1 -1 -1297 -651 +Curve -1404 -647 -1510 -643 +<-------EndPath +Path 3 2 0 -1510 -643 +Curve -1525 -641 -1539 -639 +<-------EndPath +Path 3 1 0 -1539 -639 +Curve -904 -505 -709 -290 +Curve -686 -259 -663 -227 +Curve -520 18 -920 -67 +Curve -1012 -77 -1104 -86 +<-------EndPath +Path 3 2 0 -1104 -86 +Curve -1104 -76 -1111 -77 +<-------EndPath +Path 3 1 0 -1111 -77 +Curve -1238 -88 -1366 -81 +Curve -1433 -74 -1499 -67 +Curve -1502 -67 -1504 -66 +Curve -1566 -53 -1628 -39 +Curve -1755 -4 -1847 43 +<-------EndPath +Path 3 1 -1 -1847 43 +Curve -1850 40 -1852 36 +<-------EndPath +Path 3 1 0 -1852 36 +Curve -1852 36 -1852 35 +Curve -1929 71 -1977 132 +Curve -1863 94 -1749 55 +Curve -1725 54 -1700 52 +<-------EndPath +Path 3 1 -1 -1700 52 +Curve -1698 54 -1695 56 +<-------EndPath +Path 3 3 0 -1695 56 +Curve -1674 34 -1653 12 +<-------EndPath +Path 1 1 0 -799 -2086 +Curve -803 -2085 -807 -2084 +<-------EndPath +Path 0 1 0 -798 -2084 +Curve -802 -2082 -805 -2080 +Curve -890 -2036 -928 -1956 +Curve -928 -1969 -927 -1982 +<-------EndPath +Path 3 3 0 214 -1472 +Curve 212 -1465 209 -1457 +<-------EndPath +Path 0 0 0 866 -3337 +Curve 866 -3307 866 -3277 +Curve 864 -3182 829 -3137 +<-------EndPath +Path 0 0 0 1589 -2517 +Curve 1591 -2534 1592 -2551 +Curve 1568 -2536 1546 -2507 +Curve 1507 -2457 1473 -2366 +Curve 1473 -2344 1473 -2322 +<-------EndPath +Path 0 1 0 1473 -2366 +Curve 1453 -2312 1435 -2243 +Curve 1435 -2242 1435 -2241 +<-------EndPath +Path 0 1 -1 1435 -2241 +Curve 1448 -2238 1461 -2235 +Curve 1563 -2321 1659 -2354 +Curve 1873 -2428 2058 -2232 +Curve 2295 -1981 2061 -1685 +Curve 2115 -1641 2168 -1597 +<-------EndPath +Path 0 1 0 2168 -1597 +Curve 2175 -1583 2182 -1569 +<-------EndPath +Path 0 1 -1 2182 -1569 +Curve 2122 -1627 2061 -1685 +Curve 2006 -1616 1925 -1544 +Curve 1924 -1531 1922 -1517 +Curve 2096 -1266 2010 -1055 +<-------EndPath +Path 0 5 -1 2010 -1055 +Curve 2054 -1043 2098 -1030 +<-------EndPath +Path 1 1 0 1435 -2241 +Curve 1421 -2190 1410 -2132 +<-------EndPath +Path 2 3 -1 438 -2033 +Curve 451 -2028 464 -2023 +<-------EndPath +Path 3 4 0 409 -717 +Curve 390 -773 371 -829 +Curve 364 -857 356 -884 +<-------EndPath +Path 1 1 0 1777 -792 +Curve 1794 -804 1810 -815 +<-------EndPath +Path 1 5 -1 1810 -815 +Curve 1957 -928 2010 -1055 +<-------EndPath +Path 1 1 0 1469 -777 +Curve 1469 -767 1469 -757 +<-------EndPath +Path 5 1 -1 1810 -815 +Curve 1812 -812 1814 -808 +<-------EndPath +Path 0 0 0 2168 -1557 +Curve 2175 -1563 2182 -1569 +<-------EndPath +Path 4 1 0 1290 -393 +Curve 1275 -392 1260 -390 +<-------EndPath +Path 3 -1 0 892 -696 +Curve 899 -704 905 -712 +<-------EndPath +Path -1 3 -1 892 -696 +Curve 901 -703 909 -709 +<-------EndPath +Path 4 3 -1 644 -709 +Curve 647 -709 649 -708 +Curve 649 -713 649 -717 +<-------EndPath +Path 4 3 0 649 -717 +Curve 680 -742 711 -767 +<-------EndPath +Path 4 3 -1 409 -717 +Curve 409 -713 409 -709 +Curve 419 -709 429 -709 +<-------EndPath +Path 4 3 0 429 -709 +Curve 466 -387 644 -709 +<-------EndPath +Path 1 -1 -1 274 -709 +Curve 279 -711 283 -712 +<-------EndPath +Path 1 2 0 283 -684 +Curve 279 -697 274 -709 +<-------EndPath +Path -1 2 -1 274 -709 +Curve 279 -709 284 -709 +<-------EndPath +Path 3 2 -1 258 113 +Curve 295 73 332 32 +Curve 312 77 291 122 +Curve 290 126 288 129 +Curve 278 156 267 182 +Curve 164 447 139 755 +<-------EndPath +Path 3 2 0 139 755 +Curve 139 756 139 756 +<-------EndPath +Path 3 2 -1 139 756 +Curve 134 818 132 883 +Curve 132 983 131 1083 +Curve 131 1086 131 1088 +Curve 132 1109 132 1129 +Curve 136 1203 140 1276 +Curve 153 1469 186 1657 +Curve 211 1798 224 1956 +Curve 231 2078 238 2200 +Curve 239 2230 239 2259 +Curve 240 2331 240 2403 +Curve 240 2405 240 2407 +Curve 240 2426 240 2445 +Curve 241 2478 241 2511 +Curve 243 2564 244 2616 +Curve 244 2620 244 2623 +Curve 244 2624 244 2625 +Curve 247 2671 249 2717 +Curve 253 2770 257 2823 +Curve 262 2874 267 2925 +Curve 268 2934 269 2943 +Curve 316 3266 450 3594 +Curve 574 3898 869 4042 +Curve 940 4076 1011 4109 +<-------EndPath +Path -1 2 0 1011 4109 +Curve 846 4069 675 3980 +Curve 442 3859 308 3946 +Curve 174 4032 129 4071 +Curve 102 4038 -128 4114 +Curve -26 3993 76 3872 +Curve 119 3781 -306 3899 +<-------EndPath +Path -1 7 0 -306 3899 +Curve -458 3942 -671 4011 +Curve -505 3903 -385 3801 +<-------EndPath +Path -1 3 0 -385 3801 +Curve -188 3632 -112 3478 +Curve -67 3385 -32 3284 +Curve 29 3109 57 2928 +<-------EndPath +Path -1 6 0 57 2928 +Curve 56 2928 54 2928 +Curve 56 2928 57 2928 +<-------EndPath +Path -1 3 0 57 2928 +Curve 64 2877 70 2825 +Curve 79 2727 80 2628 +Curve 79 2570 77 2512 +Curve 75 2463 72 2413 +Curve 53 2112 15 1813 +Curve 0 1678 -15 1542 +Curve -15 1541 -15 1540 +Curve -26 1415 -36 1290 +Curve -36 1289 -36 1288 +Curve -37 1270 -38 1251 +<-------EndPath +Path -1 4 0 -38 1251 +Curve -129 1446 -304 1264 +Curve -401 1164 -431 1011 +Curve -368 1381 -671 1380 +Curve -912 1379 -1111 1258 +<-------EndPath +Path -1 4 -1 -1111 1258 +Curve -1111 1246 -1111 1233 +<-------EndPath +Path -1 4 0 -1111 1233 +Curve -1259 1153 -1272 958 +<-------EndPath +Path -1 1 0 -1272 958 +Curve -1273 931 -1273 903 +Curve -1273 893 -1272 883 +<-------EndPath +Path -1 1 -1 -1272 883 +Curve -1282 883 -1291 883 +<-------EndPath +Path -1 1 0 -1291 883 +Curve -1615 1099 -1965 958 +Curve -2265 836 -2356 439 +Curve -2358 432 -2359 424 +<-------EndPath +Path -1 0 0 -2359 424 +Curve -2442 41 -2303 -302 +Curve -2219 -509 -2053 -477 +<-------EndPath +Path -1 0 -1 -2053 -477 +Curve -2052 -487 -2051 -497 +<-------EndPath +Path 3 2 0 258 114 +Curve 258 114 258 113 +<-------EndPath +Path 3 2 -1 59 1281 +Curve 59 1222 58 1163 +Curve 59 1025 72 887 +Curve 73 883 73 878 +Curve 78 820 86 763 +Curve 87 758 88 753 +Curve 88 749 87 744 +Curve 83 698 79 652 +Curve 79 620 79 587 +Curve 88 339 235 158 +Curve 242 141 249 123 +Curve 254 119 258 114 +<-------EndPath +Path 4 3 0 249 1091 +Curve 254 1141 259 1190 +Curve 261 1200 262 1210 +<-------EndPath +Path 1 2 0 -851 -709 +Curve -849 -704 -846 -699 +<-------EndPath +Path 1 2 -1 -852 -709 +Curve -852 -709 -851 -709 +<-------EndPath +Path -1 1 0 -969 -712 +Curve -970 -711 -971 -709 +<-------EndPath +Path 2 1 -1 -971 -709 +Curve -1041 -709 -1111 -709 +Curve -1111 -684 -1111 -658 +<-------EndPath +Path -1 1 0 -1297 -651 +Curve -1311 -652 -1325 -652 +Curve -1418 -648 -1510 -643 +<-------EndPath +Path 2 1 -1 -1510 -643 +Curve -1531 -643 -1552 -642 +<-------EndPath +Path 2 1 0 -1552 -642 +Curve -1546 -641 -1539 -639 +<-------EndPath +Path 1 1 0 -1539 -639 +Curve -1544 -639 -1548 -638 +Curve -1554 -637 -1560 -636 +<-------EndPath +Path 2 1 0 -1104 -86 +Curve -1105 -86 -1105 -86 +Curve -1108 -86 -1111 -86 +<-------EndPath +Path 2 -1 0 -1111 -86 +Curve -1111 -82 -1111 -77 +<-------EndPath +Path 1 -1 -1 -1111 -77 +Curve -1111 -82 -1111 -86 +<-------EndPath +Path 2 3 0 -1091 51 +Curve -1101 48 -1111 45 +<-------EndPath +Path 2 1 0 -1111 45 +Curve -1111 48 -1111 50 +Curve -1101 51 -1091 51 +<-------EndPath +Path 3 1 0 -1091 51 +Curve -757 58 -458 188 +Curve -203 300 -77 588 +<-------EndPath +Path 3 3 0 -77 588 +Curve -84 520 -91 451 +<-------EndPath +Path 1 3 0 -1111 45 +Curve -1232 35 -1352 24 +Curve -1419 27 -1486 29 +Curve -1548 41 -1599 72 +Curve -1658 109 -1700 159 +Curve -1785 264 -1838 345 +<-------EndPath +Path 1 3 -1 -1838 345 +Curve -1845 344 -1852 342 +<-------EndPath +Path 1 3 0 -1852 342 +Curve -1853 342 -1853 342 +Curve -1832 215 -1749 117 +Curve -1722 87 -1695 56 +<-------EndPath +Path 1 4 -1 -1272 958 +Curve -1251 1113 -1013 1191 +Curve -903 1227 -766 1180 +Curve -500 1090 -378 781 +<-------EndPath +Path 1 1 0 -378 781 +Curve -383 771 -387 761 +<-------EndPath +Path 4 4 0 -1111 1233 +Curve -1101 1238 -1091 1243 +<-------EndPath +Path 1 3 0 -48 1042 +Curve -49 1037 -49 1031 +Curve -52 963 -55 894 +Curve -63 779 -71 663 +Curve -74 626 -77 588 +<-------EndPath +Path 4 3 0 -38 1251 +Curve -41 1210 -43 1169 +Curve -43 1169 -43 1168 +Curve -46 1105 -48 1042 +<-------EndPath +Path 4 1 -1 -48 1042 +Curve -60 1043 -71 1043 +Curve -256 1036 -378 781 +<-------EndPath +Path 1 0 -1 -1819 -435 +Curve -1927 -416 -2013 -379 +Curve -2014 -379 -2015 -378 +Curve -2316 -250 -2354 87 +Curve -2374 266 -2359 424 +<-------EndPath +Path 3 2 -1 -311 3883 +Curve 11 3769 74 3370 +Curve 112 3123 142 2834 +Curve 152 2731 162 2628 +Curve 166 2570 170 2512 +Curve 171 2479 172 2445 +Curve 172 2426 172 2407 +Curve 172 2405 172 2403 +Curve 171 2333 169 2262 +Curve 159 2079 124 1896 +Curve 90 1716 73 1533 +Curve 62 1408 59 1282 +<-------EndPath +Path 3 2 0 59 1282 +Curve 59 1282 59 1281 +<-------EndPath +Path 7 2 -1 -306 3899 +Curve -309 3891 -311 3883 +<-------EndPath +Path 7 3 -1 -311 3883 +Curve -348 3842 -385 3801 +<-------EndPath +Path 3 3 0 229 1083 +Curve 239 1087 249 1091 +<-------EndPath +!======EndShape +=======BeginShape +Path 0 1 -1 733 -731 +Curve 762 -712 790 -692 +Curve 800 -683 809 -674 +Curve 851 -634 883 -579 +Curve 950 -465 965 -337 +Curve 983 -189 1067 -100 +Curve 1147 -14 1233 65 +Curve 1248 77 1262 88 +<-------EndPath +Path 0 6 -1 1262 88 +Curve 1290 102 1318 115 +Curve 1369 131 1387 169 +<-------EndPath +Path 0 -1 0 1387 169 +Curve 1379 133 1344 98 +Curve 1317 71 1281 52 +Curve 1267 46 1252 39 +Curve 1145 -2 1090 -95 +Curve 1036 -185 1019 -301 +Curve 1004 -413 966 -517 +Curve 928 -623 833 -691 +Curve 786 -724 733 -731 +<-------EndPath +Path 1 -1 0 733 -731 +Curve 690 -730 647 -728 +Curve 641 -727 634 -725 +<-------EndPath +Path 1 3 0 634 -725 +Curve 654 -721 674 -717 +Curve 675 -717 676 -717 +Curve 733 -703 769 -668 +<-------EndPath +Path 1 2 0 769 -668 +Curve 778 -659 787 -649 +Curve 813 -617 827 -575 +<-------EndPath +Path 1 3 0 827 -575 +Curve 828 -572 829 -568 +Curve 830 -567 830 -565 +Curve 841 -526 851 -486 +<-------EndPath +Path 1 4 0 851 -486 +Curve 854 -473 857 -459 +<-------EndPath +Path 1 -1 0 857 -459 +Curve 866 -402 875 -344 +Curve 877 -332 878 -320 +<-------EndPath +Path 1 5 0 878 -320 +Curve 882 -287 886 -253 +<-------EndPath +Path 1 2 0 886 -253 +Curve 891 -209 896 -165 +<-------EndPath +Path 1 5 0 896 -165 +Curve 899 -143 901 -120 +Curve 904 -87 916 -61 +Curve 916 -61 916 -60 +Curve 947 9 1033 23 +<-------EndPath +Path 1 -1 0 1033 23 +Curve 1034 23 1034 23 +Curve 1040 24 1045 25 +<-------EndPath +Path 1 3 0 1045 25 +Curve 1152 44 1246 83 +Curve 1254 87 1261 90 +<-------EndPath +Path 1 6 -1 1261 90 +Curve 1262 89 1262 88 +<-------EndPath +Path 3 2 1 -1199 -608 +Curve -1194 -608 -1189 -607 +Curve -1090 -603 -991 -599 +Curve -876 -594 -760 -589 +Curve -645 -579 -529 -585 +Curve -417 -595 -304 -605 +Curve -194 -612 -84 -619 +Curve 33 -626 149 -632 +Curve 264 -640 379 -647 +Curve 496 -652 612 -657 +Curve 691 -663 769 -668 +<-------EndPath +Path 3 2 1 827 -575 +Curve 781 -573 735 -570 +Curve 623 -561 510 -551 +Curve 397 -547 284 -542 +Curve 204 -538 124 -534 +Curve 120 -534 116 -533 +Curve 113 -533 110 -533 +Curve 88 -531 65 -529 +Curve 25 -526 -15 -522 +<-------EndPath +Path 3 4 1 -15 -522 +Curve -91 -517 -167 -512 +Curve -280 -504 -392 -495 +Curve -508 -484 -623 -472 +Curve -718 -465 -813 -458 +Curve -936 -445 -1058 -431 +<-------EndPath +Path 3 0 1 -1058 -431 +Curve -1058 -430 -1057 -428 +Curve -1043 -384 -1029 -340 +<-------EndPath +Path 3 -1 1 -1029 -340 +Curve -1019 -341 -1009 -342 +<-------EndPath +Path 3 4 1 -1009 -342 +Curve -914 -352 -818 -362 +Curve -700 -370 -582 -378 +Curve -472 -382 -362 -386 +Curve -244 -397 -125 -408 +Curve -10 -418 106 -428 +Curve 216 -439 325 -450 +<-------EndPath +Path 3 -1 1 325 -450 +Curve 332 -451 339 -452 +<-------EndPath +Path 3 4 1 339 -452 +Curve 454 -467 569 -482 +Curve 682 -486 794 -489 +Curve 823 -488 851 -486 +<-------EndPath +Path -1 3 0 563 -725 +Curve 611 -720 634 -725 +<-------EndPath +Path -1 -1 1 647 -728 +Curve 605 -727 563 -725 +<-------EndPath +Path 3 -1 1 563 -725 +Curve 354 -707 145 -689 +Curve 29 -681 -88 -673 +Curve -424 -660 -760 -646 +Curve -982 -641 -1200 -643 +<-------EndPath +Path 3 -1 -1 -1200 -643 +Curve -1207 -630 -1213 -616 +<-------EndPath +Path 3 0 1 -1213 -616 +Curve -1206 -612 -1199 -608 +<-------EndPath +Path 2 0 1 -1199 -608 +Curve -1195 -605 -1190 -602 +Curve -1125 -556 -1087 -492 +<-------EndPath +Path 2 4 -1 -1087 -492 +Curve -1079 -498 -1070 -503 +<-------EndPath +Path 2 4 1 -1070 -503 +Curve -995 -505 -919 -507 +Curve -843 -504 -767 -510 +Curve -695 -516 -623 -522 +Curve -549 -526 -475 -529 +Curve -434 -530 -392 -530 +Curve -360 -531 -327 -532 +Curve -251 -536 -175 -539 +Curve -171 -539 -167 -539 +Curve -92 -537 -16 -535 +<-------EndPath +Path 2 2 1 -16 -535 +Curve -15 -535 -14 -535 +Curve 26 -533 66 -531 +Curve 88 -532 110 -533 +<-------EndPath +Path -1 -1 1 328 -428 +Curve 335 -429 341 -429 +<-------EndPath +Path -1 4 -1 341 -429 +Curve 340 -441 339 -452 +<-------EndPath +Path 4 -1 -1 328 -428 +Curve 327 -439 325 -450 +<-------EndPath +Path 4 -1 1 -1007 -311 +Curve -935 -313 -863 -314 +Curve -791 -316 -719 -318 +Curve -642 -320 -564 -321 +Curve -485 -324 -405 -327 +Curve -330 -338 -254 -348 +Curve -184 -355 -113 -362 +Curve -39 -372 35 -382 +Curve 74 -390 112 -398 +Curve 146 -404 180 -410 +Curve 254 -419 327 -428 +Curve 328 -428 328 -428 +<-------EndPath +Path 2 5 1 886 -253 +Curve 856 -267 765 -270 +Curve 765 -270 764 -270 +Curve 661 -267 558 -263 +Curve 549 -263 539 -262 +Curve 431 -255 322 -247 +Curve 322 -247 321 -247 +Curve 315 -247 308 -247 +Curve 204 -243 100 -238 +Curve 99 -238 98 -238 +Curve -16 -226 -130 -214 +Curve -249 -204 -368 -194 +Curve -463 -190 -558 -185 +Curve -668 -176 -777 -167 +Curve -889 -157 -999 -181 +<-------EndPath +Path 2 0 1 -999 -181 +Curve -985 -109 -955 -48 +<-------EndPath +Path 2 5 1 -955 -48 +Curve -849 -58 -742 -68 +Curve -627 -74 -511 -79 +Curve -407 -76 -303 -83 +Curve -196 -96 -88 -109 +Curve 21 -117 130 -125 +Curve 190 -125 250 -125 +Curve 309 -129 368 -133 +Curve 486 -144 604 -154 +Curve 720 -159 836 -164 +Curve 866 -165 896 -165 +<-------EndPath +Path 5 5 1 916 -60 +Curve 784 -65 652 -70 +Curve 537 -71 421 -71 +Curve 337 -69 253 -67 +Curve 221 -65 189 -63 +Curve 74 -52 -42 -40 +Curve -149 -30 -256 -20 +Curve -360 -14 -463 -8 +Curve -576 2 -689 11 +Curve -793 15 -896 19 +<-------EndPath +Path -1 5 1 -997 -260 +Curve -881 -263 -766 -259 +Curve -671 -259 -576 -258 +Curve -469 -262 -362 -265 +Curve -244 -268 -125 -270 +Curve -16 -271 94 -272 +Curve 207 -276 320 -280 +Curve 438 -291 556 -301 +Curve 660 -310 763 -318 +Curve 776 -319 789 -319 +Curve 832 -320 875 -320 +Curve 877 -320 878 -320 +<-------EndPath +Path -1 4 1 857 -459 +Curve 826 -458 795 -457 +Curve 795 -457 794 -457 +Curve 790 -457 786 -457 +Curve 709 -453 631 -449 +Curve 552 -444 472 -439 +Curve 407 -434 341 -429 +<-------EndPath +Path 6 2 0 1323 191 +Curve 1321 216 1319 241 +Curve 1312 277 1292 299 +<-------EndPath +Path 6 -1 1 1292 299 +Curve 1309 299 1326 298 +<-------EndPath +Path 6 8 0 1326 298 +Curve 1335 292 1344 285 +<-------EndPath +Path 6 -1 0 1344 285 +Curve 1348 281 1352 276 +Curve 1398 221 1387 169 +<-------EndPath +Path 3 6 0 1323 191 +Curve 1320 121 1261 90 +<-------EndPath +Path 3 3 1 1261 90 +Curve 1141 100 1020 110 +Curve 913 109 806 108 +Curve 697 108 587 107 +Curve 564 107 541 107 +<-------EndPath +Path 3 4 1 541 107 +Curve 451 114 361 120 +<-------EndPath +Path 3 -1 1 361 120 +Curve 361 121 361 122 +<-------EndPath +Path 3 4 1 361 122 +Curve 424 136 478 190 +<-------EndPath +Path 3 2 1 478 190 +Curve 482 190 486 189 +Curve 602 184 717 179 +Curve 833 175 949 170 +Curve 985 169 1020 168 +Curve 1100 171 1180 173 +Curve 1252 182 1323 191 +<-------EndPath +Path -1 -1 0 1279 314 +Curve 1279 313 1278 311 +<-------EndPath +Path -1 1 0 1278 311 +Curve 1276 313 1273 315 +Curve 1276 315 1279 314 +<-------EndPath +Path -1 8 0 1279 314 +Curve 1306 310 1326 298 +<-------EndPath +Path 1 -1 0 1278 311 +Curve 1285 305 1292 299 +<-------EndPath +Path 1 2 1 1292 299 +Curve 1051 307 809 314 +<-------EndPath +Path 1 -1 0 809 314 +Curve 884 344 966 346 +Curve 1094 349 1058 462 +Curve 1044 506 1044 553 +Curve 1044 583 1032 588 +Curve 1067 591 1102 593 +Curve 1145 602 1188 610 +Curve 1249 622 1310 640 +Curve 1325 643 1340 645 +Curve 1343 645 1346 644 +Curve 1354 642 1359 636 +<-------EndPath +Path 1 8 0 1359 636 +Curve 1361 625 1363 613 +Curve 1354 531 1321 446 +Curve 1293 374 1279 314 +<-------EndPath +Path -1 8 0 1344 285 +Curve 1402 371 1467 455 +Curve 1516 518 1548 582 +Curve 1499 606 1442 612 +Curve 1393 617 1359 636 +<-------EndPath +Path 5 3 1 -724 137 +Curve -614 120 -504 102 +Curve -395 86 -285 69 +Curve -179 64 -72 58 +Curve 38 55 148 52 +Curve 150 52 151 52 +Curve 187 50 223 48 +Curve 280 46 336 43 +Curve 358 42 379 41 +Curve 498 35 617 29 +Curve 729 21 842 23 +Curve 938 24 1033 25 +<-------EndPath +Path 5 -1 -1 1033 25 +Curve 1033 24 1033 23 +<-------EndPath +Path -1 3 1 1033 25 +Curve 1039 25 1045 25 +<-------EndPath +Path 4 3 1 541 107 +Curve 499 103 456 98 +Curve 418 97 379 96 +Curve 359 96 338 96 +Curve 282 100 225 103 +Curve 190 107 154 110 +Curve 74 117 -7 124 +Curve -117 136 -226 148 +Curve -345 161 -463 174 +Curve -572 180 -681 185 +<-------EndPath +Path 4 0 1 -681 185 +Curve -680 186 -679 187 +Curve -666 203 -653 218 +<-------EndPath +Path 4 3 1 -653 218 +Curve -564 216 -474 213 +Curve -438 215 -402 217 +<-------EndPath +Path 4 -1 1 -402 217 +Curve -320 215 -238 212 +<-------EndPath +Path 4 3 1 -238 212 +Curve -131 197 -23 182 +Curve 87 160 183 131 +Curve 224 146 259 163 +<-------EndPath +Path 4 -1 1 259 163 +Curve 308 157 356 151 +<-------EndPath +Path 4 4 1 356 151 +Curve 357 136 361 122 +<-------EndPath +Path 4 -1 1 361 122 +Curve 358 122 355 121 +Curve 358 121 361 120 +<-------EndPath +Path 6 -1 0 515 322 +Curve 509 339 502 355 +Curve 633 412 723 464 +Curve 733 435 731 392 +Curve 729 352 742 316 +<-------EndPath +Path 6 2 1 742 316 +Curve 629 319 515 322 +<-------EndPath +Path -1 2 1 515 322 +Curve -65 340 -644 357 +<-------EndPath +Path -1 -1 1 -644 357 +Curve -654 357 -664 357 +<-------EndPath +Path -1 0 1 -664 357 +Curve -666 359 -667 360 +Curve -669 363 -671 365 +Curve -675 370 -679 374 +<-------EndPath +Path -1 8 1 -679 374 +Curve -618 459 -556 544 +Curve -507 607 -475 671 +Curve -524 695 -581 701 +Curve -630 706 -664 725 +<-------EndPath +Path -1 6 1 -664 725 +Curve -669 731 -677 733 +Curve -680 734 -683 734 +Curve -693 733 -702 732 +<-------EndPath +Path -1 6 -1 -702 732 +Curve -704 732 -705 731 +<-------EndPath +Path -1 1 1 -705 731 +Curve -709 730 -713 729 +Curve -774 714 -835 699 +Curve -878 691 -921 682 +Curve -956 680 -991 677 +Curve -979 672 -979 642 +Curve -979 595 -965 551 +Curve -929 438 -1057 435 +Curve -1155 433 -1244 389 +Curve -1271 375 -1281 404 +Curve -1294 441 -1292 481 +Curve -1290 524 -1300 553 +Curve -1390 501 -1521 444 +Curve -1478 337 -1446 223 +Curve -1420 131 -1401 36 +Curve -1398 16 -1394 -5 +Curve -1376 -108 -1384 -213 +Curve -1390 -303 -1402 -391 +Curve -1443 -378 -1501 -418 +Curve -1580 -471 -1527 -550 +Curve -1517 -563 -1507 -576 +Curve -1507 -576 -1506 -576 +<-------EndPath +Path -1 6 1 -1506 -576 +Curve -1506 -577 -1506 -577 +Curve -1474 -614 -1438 -628 +Curve -1414 -632 -1389 -636 +<-------EndPath +Path -1 0 1 -1389 -636 +Curve -1351 -640 -1312 -644 +<-------EndPath +Path -1 -1 1 -1312 -644 +Curve -1256 -644 -1200 -643 +<-------EndPath +Path 2 -1 1 742 316 +Curve 776 315 809 314 +<-------EndPath +Path 4 -1 1 356 151 +Curve 354 174 358 198 +<-------EndPath +Path 4 2 1 358 198 +Curve 418 194 478 190 +<-------EndPath +Path 2 -1 1 358 198 +Curve 356 198 354 198 +<-------EndPath +Path 2 3 1 354 198 +Curve 308 200 261 202 +Curve 151 206 41 210 +Curve -70 217 -180 224 +Curve -208 227 -236 230 +<-------EndPath +Path 2 -1 1 -236 230 +Curve -320 243 -404 255 +<-------EndPath +Path 2 3 1 -404 255 +Curve -519 265 -634 274 +<-------EndPath +Path 2 0 1 -634 274 +Curve -633 299 -644 324 +<-------EndPath +Path 2 -1 -1 -644 324 +Curve -644 341 -644 357 +<-------EndPath +Path -1 3 1 259 163 +Curve 306 184 354 198 +<-------EndPath +Path 1 6 -1 -904 239 +Curve -1014 237 -1129 242 +Curve -1258 247 -1210 198 +Curve -1166 152 -1220 152 +Curve -1352 153 -1339 48 +Curve -1335 13 -1315 -34 +Curve -1261 -155 -1229 -284 +Curve -1212 -354 -1224 -416 +Curve -1237 -478 -1280 -533 +Curve -1282 -535 -1283 -537 +Curve -1285 -539 -1286 -540 +Curve -1296 -551 -1305 -561 +Curve -1324 -575 -1342 -588 +Curve -1361 -599 -1381 -602 +Curve -1436 -612 -1500 -570 +Curve -1503 -573 -1506 -576 +<-------EndPath +Path 0 6 1 -1344 -633 +Curve -1334 -629 -1324 -625 +Curve -1273 -603 -1239 -564 +Curve -1238 -563 -1237 -562 +Curve -1208 -527 -1194 -479 +Curve -1187 -454 -1180 -428 +Curve -1180 -427 -1179 -426 +Curve -1158 -342 -1148 -255 +Curve -1135 -143 -1122 -31 +Curve -1109 92 -990 112 +Curve -876 131 -777 172 +Curve -695 205 -700 298 +Curve -700 301 -700 304 +<-------EndPath +Path 0 7 1 -700 304 +Curve -700 305 -700 306 +<-------EndPath +Path 0 6 1 -700 306 +Curve -702 318 -704 330 +Curve -713 377 -745 400 +<-------EndPath +Path 0 -1 1 -745 400 +Curve -745 402 -744 403 +<-------EndPath +Path 0 8 1 -744 403 +Curve -704 397 -679 374 +<-------EndPath +Path 0 6 1 -1389 -636 +Curve -1383 -636 -1376 -635 +Curve -1362 -632 -1347 -628 +<-------EndPath +Path 0 6 -1 -1347 -628 +Curve -1346 -631 -1344 -633 +<-------EndPath +Path 1 1 1 -1402 -391 +Curve -1361 -405 -1337 -473 +Curve -1333 -485 -1337 -494 +Curve -1345 -502 -1353 -510 +Curve -1463 -566 -1434 -458 +<-------EndPath +Path 4 -1 -1 -1009 -342 +Curve -1008 -327 -1007 -311 +<-------EndPath +Path -1 5 -1 -1011 -257 +Curve -1004 -259 -997 -260 +<-------EndPath +Path 0 -1 1 -1011 -257 +Curve -1016 -283 -1021 -308 +Curve -1025 -324 -1029 -340 +<-------EndPath +Path 4 0 1 -1087 -492 +Curve -1073 -462 -1058 -431 +<-------EndPath +Path 0 5 1 -999 -181 +Curve -1002 -197 -1004 -212 +Curve -1008 -235 -1011 -257 +<-------EndPath +Path 0 5 1 -729 148 +Curve -743 141 -757 134 +Curve -758 134 -759 133 +Curve -760 133 -760 133 +Curve -766 131 -771 128 +Curve -857 95 -909 29 +Curve -921 12 -933 -6 +Curve -944 -27 -955 -48 +<-------EndPath +Path 0 -1 1 -1213 -616 +Curve -1259 -642 -1312 -644 +<-------EndPath +Path 2 4 -1 -16 -535 +Curve -16 -529 -15 -522 +<-------EndPath +Path -1 3 -1 -402 217 +Curve -403 236 -404 255 +<-------EndPath +Path -1 3 -1 -236 230 +Curve -237 221 -238 212 +<-------EndPath +Path 5 3 -1 -729 148 +Curve -727 143 -724 137 +<-------EndPath +Path 0 3 1 -681 185 +Curve -703 164 -729 148 +<-------EndPath +Path 0 -1 1 -664 357 +Curve -654 341 -644 324 +<-------EndPath +Path -1 6 1 -745 400 +Curve -748 402 -750 404 +Curve -747 404 -744 403 +<-------EndPath +Path 8 6 1 -744 403 +Curve -730 463 -702 535 +Curve -669 620 -660 702 +Curve -659 717 -664 725 +<-------EndPath +Path 7 6 -1 -700 304 +Curve -733 301 -766 298 +Curve -733 302 -700 306 +<-------EndPath +Path 0 3 1 -634 274 +Curve -635 245 -653 218 +<-------EndPath +Path 1 6 -1 -705 731 +Curve -720 724 -719 651 +Curve -717 577 -774 530 +Curve -831 483 -832 422 +<-------EndPath +Path 1 6 1 -832 422 +Curve -944 419 -933 319 +Curve -933 319 -933 318 +Curve -933 316 -933 314 +Curve -933 313 -933 312 +Curve -932 306 -931 300 +Curve -923 257 -904 239 +<-------EndPath +Path 6 6 1 -904 239 +Curve -864 240 -824 241 +Curve -764 273 -766 298 +Curve -769 318 -814 334 +Curve -824 337 -834 340 +Curve -859 346 -867 321 +<-------EndPath +Path 6 6 1 -750 404 +Curve -775 419 -813 421 +Curve -823 422 -832 422 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 2 -1 2391 3220 +Curve 2390 3220 2389 3220 +Curve 2390 3215 2391 3210 +Curve 2411 3207 2430 3204 +Curve 2439 3203 2447 3202 +Curve 2551 3191 2666 3204 +Curve 2701 3209 2735 3214 +Curve 2744 3216 2753 3217 +<-------EndPath +Path -1 9 -1 2753 3217 +Curve 2815 3220 2876 3222 +Curve 2875 3226 2874 3229 +<-------EndPath +Path -1 2 -1 2874 3229 +Curve 2881 3230 2888 3231 +<-------EndPath +Path -1 2 0 2888 3231 +Curve 2890 3233 2892 3235 +Curve 2902 3250 2911 3265 +Curve 2923 3289 2935 3313 +Curve 2939 3321 2942 3329 +<-------EndPath +Path -1 3 0 2942 3329 +Curve 2957 3320 2972 3310 +<-------EndPath +Path -1 -1 0 2972 3310 +Curve 2980 3305 2987 3300 +Curve 2988 3305 2988 3309 +<-------EndPath +Path -1 3 0 2988 3309 +Curve 2991 3315 2993 3320 +Curve 3019 3357 3055 3384 +Curve 3043 3383 3030 3382 +Curve 3022 3384 3014 3385 +<-------EndPath +Path -1 9 0 3014 3385 +Curve 3052 3483 3021 3574 +Curve 3012 3597 2999 3610 +<-------EndPath +Path -1 -1 0 2999 3610 +Curve 3003 3633 3006 3655 +<-------EndPath +Path -1 11 0 3006 3655 +Curve 3022 3649 3037 3643 +<-------EndPath +Path -1 12 0 3037 3643 +Curve 3045 3640 3052 3636 +Curve 3080 3694 3085 3739 +Curve 3065 3744 3052 3755 +Curve 3035 3768 3018 3781 +Curve 2998 3723 2977 3664 +Curve 2985 3662 2993 3659 +<-------EndPath +Path -1 11 0 2993 3659 +Curve 3000 3657 3006 3655 +<-------EndPath +Path -1 -1 0 2213 3208 +Curve 2219 3205 2225 3201 +<-------EndPath +Path 0 2 0 2228 3212 +Curve 2227 3215 2226 3217 +Curve 2226 3218 2225 3219 +Curve 2223 3231 2220 3243 +Curve 2217 3249 2214 3254 +Curve 2203 3273 2192 3291 +<-------EndPath +Path 0 5 0 2192 3291 +Curve 2205 3311 2217 3330 +<-------EndPath +Path 0 1 -1 2217 3330 +Curve 2219 3329 2220 3328 +Curve 2233 3316 2246 3303 +Curve 2271 3272 2278 3235 +Curve 2281 3236 2284 3237 +Curve 2285 3232 2286 3227 +<-------EndPath +Path 0 -1 -1 2286 3227 +Curve 2257 3220 2228 3212 +<-------EndPath +Path 2 -1 -1 2228 3212 +Curve 2221 3210 2213 3208 +<-------EndPath +Path 2 -1 0 2213 3208 +Curve 2156 3245 2137 3307 +<-------EndPath +Path 2 -1 -1 2137 3307 +Curve 2138 3308 2138 3308 +<-------EndPath +Path 2 3 0 2138 3308 +Curve 2164 3295 2184 3302 +<-------EndPath +Path 2 5 0 2184 3302 +Curve 2188 3297 2192 3291 +<-------EndPath +Path 3 -1 0 2129 3358 +Curve 2124 3356 2119 3353 +Curve 2117 3347 2114 3340 +Curve 2114 3333 2119 3328 +Curve 2125 3322 2132 3322 +Curve 2138 3322 2144 3328 +Curve 2147 3334 2149 3340 +<-------EndPath +Path 3 4 0 2149 3340 +Curve 2159 3330 2169 3320 +<-------EndPath +Path 3 5 0 2169 3320 +Curve 2177 3311 2184 3302 +<-------EndPath +Path -1 -1 0 2137 3308 +Curve 2137 3308 2137 3307 +<-------EndPath +Path 3 -1 0 2138 3308 +Curve 2138 3308 2137 3308 +Curve 2052 3340 2073 3441 +<-------EndPath +Path 3 5 0 2073 3441 +Curve 2075 3435 2077 3429 +Curve 2079 3423 2081 3416 +<-------EndPath +Path 3 4 0 2081 3416 +Curve 2095 3383 2120 3365 +Curve 2125 3362 2129 3358 +<-------EndPath +Path -1 4 0 2129 3358 +Curve 2139 3349 2149 3340 +<-------EndPath +Path 5 1 0 2457 3346 +Curve 2443 3376 2412 3385 +Curve 2411 3386 2409 3386 +Curve 2384 3390 2358 3394 +Curve 2275 3399 2222 3336 +Curve 2220 3333 2217 3330 +<-------EndPath +Path 5 4 0 2040 3610 +Curve 2061 3594 2081 3578 +Curve 2094 3564 2106 3549 +Curve 2159 3474 2085 3419 +Curve 2083 3418 2081 3416 +<-------EndPath +Path 5 4 0 2169 3320 +Curve 2168 3355 2176 3383 +Curve 2185 3411 2203 3431 +Curve 2220 3449 2246 3459 +Curve 2283 3475 2341 3475 +Curve 2357 3474 2373 3473 +Curve 2396 3467 2418 3461 +Curve 2491 3428 2500 3322 +<-------EndPath +Path 5 2 0 2500 3322 +Curve 2500 3322 2499 3321 +Curve 2485 3312 2470 3303 +Curve 2469 3303 2468 3302 +<-------EndPath +Path 5 0 0 2468 3302 +Curve 2463 3324 2457 3346 +<-------EndPath +Path 1 0 -1 2457 3346 +Curve 2426 3342 2402 3330 +Curve 2352 3307 2331 3250 +Curve 2327 3249 2323 3248 +Curve 2324 3242 2324 3236 +<-------EndPath +Path 1 -1 -1 2324 3236 +Curve 2305 3232 2286 3227 +<-------EndPath +Path -1 2 0 2416 3260 +Curve 2400 3241 2391 3220 +<-------EndPath +Path -1 0 -1 2324 3236 +Curve 2370 3248 2416 3260 +<-------EndPath +Path 2 0 0 2416 3260 +Curve 2437 3283 2468 3302 +<-------EndPath +Path -1 6 0 2021 3952 +Curve 2023 3955 2024 3958 +<-------EndPath +Path -1 7 0 2024 3958 +Curve 2025 3954 2025 3950 +<-------EndPath +Path -1 -1 0 2025 3950 +Curve 2023 3951 2021 3952 +<-------EndPath +Path 6 -1 0 2021 3952 +Curve 1974 3974 1953 4025 +Curve 1941 4056 1928 4087 +<-------EndPath +Path 6 6 0 1928 4087 +Curve 1941 4117 1954 4147 +Curve 1955 4149 1956 4151 +Curve 1957 4152 1957 4152 +Curve 2012 4155 2055 4191 +Curve 2061 4198 2067 4204 +<-------EndPath +Path -1 -1 0 1928 4087 +Curve 1921 4068 1914 4048 +Curve 1896 3998 1889 3948 +Curve 1882 3893 1891 3839 +Curve 1900 3790 1909 3741 +Curve 1920 3691 1945 3646 +Curve 1971 3597 2004 3554 +Curve 2034 3517 2063 3479 +<-------EndPath +Path -1 5 0 2063 3479 +Curve 2063 3479 2063 3478 +Curve 2064 3476 2064 3474 +Curve 2069 3458 2073 3441 +<-------EndPath +Path 4 4 0 2391 3908 +Curve 2393 3891 2384 3881 +Curve 2358 3848 2375 3802 +Curve 2376 3801 2376 3799 +Curve 2381 3781 2385 3762 +Curve 2385 3758 2385 3754 +Curve 2385 3754 2385 3753 +Curve 2385 3752 2385 3750 +Curve 2385 3735 2384 3719 +Curve 2384 3719 2384 3718 +Curve 2378 3684 2357 3649 +Curve 2346 3629 2342 3608 +Curve 2338 3589 2340 3570 +Curve 2343 3527 2345 3484 +<-------EndPath +Path 4 -1 0 2040 3610 +Curve 2038 3652 2036 3694 +Curve 2034 3761 2032 3828 +<-------EndPath +Path 4 1 0 2032 3828 +Curve 2042 3832 2052 3835 +<-------EndPath +Path 4 7 0 2052 3835 +Curve 2071 3842 2090 3848 +Curve 2190 3880 2300 3898 +<-------EndPath +Path 4 0 -1 2300 3898 +Curve 2302 3899 2304 3899 +<-------EndPath +Path 4 7 0 2304 3899 +Curve 2311 3900 2317 3900 +Curve 2354 3904 2391 3908 +Curve 2485 3915 2574 3908 +<-------EndPath +Path 4 4 0 2574 3908 +Curve 2587 3872 2599 3835 +Curve 2611 3788 2622 3741 +Curve 2631 3693 2640 3644 +Curve 2647 3599 2653 3553 +Curve 2659 3520 2664 3486 +<-------EndPath +Path 4 5 0 2664 3486 +Curve 2621 3445 2593 3370 +<-------EndPath +Path 4 2 0 2593 3370 +Curve 2560 3353 2526 3336 +Curve 2513 3329 2500 3322 +<-------EndPath +Path 5 5 0 2064 3474 +Curve 2064 3477 2063 3479 +<-------EndPath +Path 5 -1 0 2063 3479 +Curve 2046 3544 2040 3610 +<-------EndPath +Path 1 -1 0 2032 3828 +Curve 2032 3840 2031 3851 +<-------EndPath +Path 1 7 -1 2031 3851 +Curve 2042 3843 2052 3835 +<-------EndPath +Path 7 -1 0 2031 3851 +Curve 2031 3886 2031 3921 +Curve 2028 3935 2025 3948 +Curve 2025 3949 2025 3950 +<-------EndPath +Path 0 7 -1 2300 3898 +Curve 2300 3899 2300 3899 +Curve 2302 3899 2304 3899 +<-------EndPath +Path -1 3 -1 2972 3310 +Curve 2980 3310 2988 3309 +<-------EndPath +Path 10 3 0 2900 3426 +Curve 2887 3435 2874 3443 +Curve 2873 3408 2852 3379 +<-------EndPath +Path 10 2 0 2852 3379 +Curve 2847 3382 2841 3385 +Curve 2875 3478 2878 3571 +Curve 2879 3579 2879 3586 +Curve 2888 3579 2907 3593 +<-------EndPath +Path 10 9 0 2907 3593 +Curve 2924 3546 2918 3488 +Curve 2913 3451 2900 3426 +<-------EndPath +Path 3 9 0 2900 3426 +Curve 2930 3409 2965 3398 +Curve 2990 3392 3014 3385 +<-------EndPath +Path 3 2 0 2942 3329 +Curve 2909 3349 2876 3368 +Curve 2864 3374 2852 3379 +<-------EndPath +Path 9 -1 0 2996 3464 +Curve 2993 3472 2989 3480 +Curve 2981 3483 2973 3486 +Curve 2965 3483 2957 3480 +Curve 2950 3473 2950 3464 +Curve 2950 3454 2957 3447 +Curve 2963 3441 2973 3441 +Curve 2983 3441 2989 3447 +Curve 2996 3454 2996 3464 +<-------EndPath +Path 9 2 0 2753 3217 +Curve 2740 3234 2727 3251 +Curve 2715 3267 2711 3310 +Curve 2706 3359 2712 3444 +Curve 2712 3445 2712 3446 +<-------EndPath +Path 9 9 0 2712 3446 +Curve 2738 3456 2761 3470 +<-------EndPath +Path 9 2 0 2761 3470 +Curve 2751 3362 2762 3313 +Curve 2765 3306 2767 3298 +Curve 2795 3219 2874 3229 +<-------EndPath +Path 9 2 0 2712 3446 +Curve 2713 3455 2713 3463 +<-------EndPath +Path 9 5 0 2713 3463 +Curve 2736 3488 2759 3512 +Curve 2763 3517 2767 3521 +<-------EndPath +Path 9 2 0 2767 3521 +Curve 2764 3496 2761 3470 +<-------EndPath +Path 5 2 0 2713 3463 +Curve 2657 3409 2593 3370 +<-------EndPath +Path 5 4 0 2664 3486 +Curve 2688 3510 2718 3522 +Curve 2744 3529 2769 3535 +Curve 2774 3536 2779 3536 +<-------EndPath +Path 5 2 0 2779 3536 +Curve 2773 3529 2767 3521 +<-------EndPath +Path 7 4 0 2884 3747 +Curve 2865 3772 2845 3796 +Curve 2793 3849 2721 3878 +Curve 2666 3899 2600 3906 +Curve 2587 3907 2574 3908 +<-------EndPath +Path 7 7 0 2574 3908 +Curve 2568 3923 2561 3938 +Curve 2538 3985 2507 4028 +Curve 2476 4069 2438 4103 +Curve 2426 4116 2414 4128 +<-------EndPath +Path 7 6 0 2414 4128 +Curve 2461 4133 2508 4137 +Curve 2561 4143 2614 4148 +Curve 2669 4156 2724 4148 +Curve 2770 4141 2815 4134 +<-------EndPath +Path 7 -1 0 2815 4134 +Curve 2822 4131 2828 4127 +Curve 2854 4110 2879 4092 +<-------EndPath +Path 7 6 0 2879 4092 +Curve 2887 4083 2895 4074 +Curve 2895 4076 2894 4077 +<-------EndPath +Path 7 -1 0 2894 4077 +Curve 2896 4076 2897 4074 +Curve 2900 3989 2902 3903 +Curve 2902 3828 2888 3763 +Curve 2886 3755 2884 3747 +<-------EndPath +Path 4 -1 0 2884 3747 +Curve 2883 3742 2882 3737 +<-------EndPath +Path 4 8 0 2882 3737 +Curve 2865 3677 2836 3623 +<-------EndPath +Path 4 2 0 2836 3623 +Curve 2812 3577 2779 3536 +<-------EndPath +Path 9 -1 0 2907 3593 +Curve 2908 3594 2908 3594 +Curve 2908 3607 2899 3615 +<-------EndPath +Path 9 2 0 2899 3615 +Curve 2929 3627 2953 3627 +<-------EndPath +Path 9 -1 0 2953 3627 +Curve 2981 3627 2999 3610 +<-------EndPath +Path 9 9 0 2999 3610 +Curve 2993 3593 2987 3576 +<-------EndPath +Path 2 -1 0 2899 3615 +Curve 2903 3604 2907 3593 +<-------EndPath +Path 2 8 0 2836 3623 +Curve 2849 3629 2862 3635 +Curve 2880 3643 2893 3654 +Curve 2910 3670 2916 3694 +<-------EndPath +Path 2 -1 0 2916 3694 +Curve 2935 3661 2953 3627 +<-------EndPath +Path 11 11 0 3029 3659 +Curve 3031 3666 3033 3672 +<-------EndPath +Path 12 11 0 3037 3643 +Curve 3045 3661 3053 3678 +Curve 3031 3684 3008 3690 +Curve 3001 3675 2993 3659 +<-------EndPath +Path 12 11 0 3028 3722 +Curve 3030 3718 3031 3713 +Curve 3036 3712 3040 3710 +Curve 3045 3710 3048 3713 +Curve 3050 3718 3052 3722 +Curve 3050 3726 3048 3730 +Curve 3044 3732 3040 3734 +Curve 3035 3734 3031 3730 +Curve 3028 3727 3028 3722 +<-------EndPath +Path 8 -1 0 2882 3737 +Curve 2889 3730 2895 3722 +Curve 2906 3708 2916 3694 +<-------EndPath +Path 2 2 0 2841 3385 +Curve 2836 3387 2830 3389 +<-------EndPath +Path 5 5 0 2664 3486 +Curve 2668 3468 2671 3449 +<-------EndPath +Path 6 6 0 2879 4092 +Curve 2887 4085 2894 4077 +<-------EndPath +Path -1 6 0 2894 4077 +Curve 2876 4125 2826 4154 +Curve 2773 4183 2731 4215 +Curve 2688 4247 2653 4287 +Curve 2634 4307 2624 4328 +Curve 2623 4330 2622 4331 +<-------EndPath +Path -1 6 -1 2622 4331 +Curve 2628 4330 2625 4343 +Curve 2619 4353 2613 4363 +Curve 2613 4364 2613 4364 +<-------EndPath +Path -1 6 0 2613 4364 +Curve 2612 4369 2611 4374 +Curve 2602 4419 2566 4428 +Curve 2511 4441 2461 4416 +Curve 2414 4393 2357 4390 +Curve 2327 4387 2296 4383 +<-------EndPath +Path -1 -1 0 2296 4383 +Curve 2279 4424 2278 4486 +Curve 2279 4507 2279 4527 +<-------EndPath +Path -1 13 0 2279 4527 +Curve 2279 4528 2279 4528 +Curve 2288 4568 2263 4603 +Curve 2228 4644 2192 4685 +Curve 2172 4704 2151 4722 +Curve 2157 4772 2162 4822 +Curve 2169 4862 2176 4902 +<-------EndPath +Path -1 13 -1 2176 4902 +Curve 2177 4906 2177 4909 +<-------EndPath +Path -1 13 0 2177 4909 +Curve 2170 4907 2162 4905 +Curve 2131 4878 2106 4844 +Curve 2083 4812 2069 4776 +Curve 2033 4785 1997 4793 +Curve 1998 4745 2041 4711 +Curve 2046 4708 2050 4704 +Curve 2048 4671 2045 4637 +Curve 2045 4584 2076 4543 +<-------EndPath +Path -1 -1 0 2076 4543 +Curve 2072 4540 2068 4536 +Curve 2067 4536 2065 4535 +Curve 2059 4484 2062 4430 +Curve 2067 4382 2072 4334 +<-------EndPath +Path -1 6 0 2072 4334 +Curve 2072 4334 2071 4334 +Curve 2030 4321 1993 4299 +Curve 1971 4286 1948 4280 +Curve 1882 4259 1902 4211 +Curve 1902 4206 1901 4201 +Curve 1903 4183 1905 4164 +Curve 1911 4142 1917 4119 +Curve 1923 4103 1928 4087 +<-------EndPath +Path -1 6 0 2815 4134 +Curve 2822 4133 2828 4131 +Curve 2846 4128 2879 4092 +<-------EndPath +Path 6 6 0 2613 4364 +Curve 2612 4364 2610 4363 +Curve 2611 4369 2611 4374 +<-------EndPath +Path 6 6 0 2622 4331 +Curve 2616 4347 2610 4363 +<-------EndPath +Path 7 7 0 2359 4057 +Curve 2376 4040 2408 4046 +Curve 2407 4071 2381 4073 +<-------EndPath +Path 6 6 0 2214 4361 +Curve 2220 4359 2225 4357 +Curve 2223 4352 2220 4346 +Curve 2207 4302 2227 4258 +Curve 2231 4251 2235 4243 +Curve 2254 4210 2279 4183 +Curve 2285 4177 2290 4171 +Curve 2294 4168 2298 4164 +<-------EndPath +Path 6 6 0 2389 4247 +Curve 2372 4210 2383 4171 +Curve 2384 4168 2385 4165 +Curve 2378 4176 2371 4187 +Curve 2357 4210 2351 4236 +<-------EndPath +Path 6 6 0 2414 4128 +Curve 2399 4143 2387 4161 +Curve 2386 4163 2385 4165 +<-------EndPath +Path 7 6 0 2024 3958 +Curve 2052 4000 2095 4027 +Curve 2143 4056 2195 4075 +Curve 2244 4091 2292 4106 +Curve 2345 4116 2398 4126 +Curve 2406 4127 2414 4128 +<-------EndPath +Path -1 6 0 2168 4360 +Curve 2162 4358 2156 4355 +Curve 2123 4348 2090 4340 +Curve 2081 4337 2072 4334 +<-------EndPath +Path -1 -1 0 2214 4361 +Curve 2211 4362 2207 4362 +<-------EndPath +Path -1 6 -1 2207 4362 +Curve 2207 4374 2194 4362 +Curve 2194 4362 2193 4361 +<-------EndPath +Path -1 6 0 2193 4361 +Curve 2185 4360 2177 4359 +<-------EndPath +Path -1 6 -1 2177 4359 +Curve 2173 4360 2168 4360 +<-------EndPath +Path -1 -1 0 2168 4360 +Curve 2185 4365 2201 4369 +Curve 2214 4370 2227 4371 +Curve 2237 4372 2246 4372 +<-------EndPath +Path -1 6 0 2246 4372 +Curve 2239 4368 2231 4364 +<-------EndPath +Path -1 6 -1 2231 4364 +Curve 2223 4363 2214 4361 +Curve 2211 4361 2207 4360 +Curve 2207 4361 2207 4362 +<-------EndPath +Path 6 6 0 2207 4362 +Curve 2201 4362 2195 4361 +Curve 2194 4361 2193 4361 +<-------EndPath +Path 13 -1 -1 2206 4377 +Curve 2220 4382 2231 4390 +Curve 2232 4388 2233 4385 +Curve 2217 4377 2201 4369 +Curve 2204 4373 2206 4377 +<-------EndPath +Path 6 6 0 2156 4355 +Curve 2167 4357 2177 4359 +<-------EndPath +Path -1 6 0 2296 4383 +Curve 2275 4379 2253 4375 +Curve 2250 4374 2246 4372 +<-------EndPath +Path 6 6 0 2231 4364 +Curve 2228 4361 2225 4357 +<-------EndPath +Path 6 6 0 2383 4171 +Curve 2390 4213 2417 4248 +<-------EndPath +Path 6 6 0 1956 4151 +Curve 1967 4172 1978 4192 +Curve 1992 4218 1995 4217 +<-------EndPath +Path -1 13 0 2076 4543 +Curve 2110 4569 2127 4612 +Curve 2128 4615 2129 4618 +Curve 2155 4588 2189 4566 +Curve 2231 4537 2279 4527 +<-------EndPath +Path 13 13 0 2050 4704 +Curve 2083 4676 2109 4642 +Curve 2119 4630 2129 4618 +Curve 2145 4664 2150 4715 +Curve 2151 4719 2151 4722 +Curve 2129 4739 2107 4756 +Curve 2090 4768 2069 4776 +Curve 2064 4761 2059 4745 +Curve 2055 4725 2050 4704 +<-------EndPath +Path 6 6 0 2031 4215 +Curve 1999 4181 1957 4152 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 1248 -825 +Curve 1227 -864 1206 -902 +Curve 1164 -963 1103 -1001 +Curve 1054 -1033 999 -1050 +Curve 944 -1067 888 -1067 +Curve 829 -1066 770 -1064 +Curve 698 -1061 630 -1038 +Curve 563 -1016 504 -977 +Curve 444 -937 399 -881 +<-------EndPath +Path -1 2 0 399 -881 +Curve 443 -844 486 -806 +<-------EndPath +Path -1 -1 0 486 -806 +Curve 490 -809 493 -811 +Curve 498 -814 503 -817 +Curve 507 -820 510 -822 +Curve 555 -849 609 -866 +Curve 674 -889 741 -895 +Curve 803 -894 865 -892 +Curve 932 -881 994 -856 +Curve 1046 -834 1097 -804 +Curve 1144 -776 1186 -739 +Curve 1189 -737 1192 -734 +Curve 1241 -690 1280 -633 +Curve 1305 -597 1305 -564 +<-------EndPath +Path -1 1 0 -487 -1037 +Curve -418 -1048 -348 -1058 +Curve -317 -1061 -286 -1063 +Curve -237 -1064 -187 -1065 +Curve -139 -1058 -91 -1050 +Curve -24 -1039 44 -1028 +Curve 93 -1016 142 -1003 +Curve 181 -989 219 -975 +<-------EndPath +Path -1 2 0 219 -975 +Curve 244 -965 269 -954 +Curve 348 -920 383 -893 +Curve 391 -887 399 -881 +<-------EndPath +Path -1 2 0 486 -806 +Curve 487 -806 487 -805 +Curve 498 -795 509 -784 +Curve 529 -762 548 -739 +<-------EndPath +Path -1 -1 0 548 -739 +Curve 575 -741 602 -743 +Curve 636 -743 670 -742 +Curve 741 -730 811 -717 +Curve 878 -701 933 -655 +Curve 986 -606 1039 -556 +Curve 1084 -506 1094 -437 +Curve 1104 -368 1097 -311 +<-------EndPath +Path -1 2 0 548 -739 +Curve 556 -729 564 -718 +Curve 585 -685 606 -652 +Curve 622 -625 623 -598 +Curve 623 -593 623 -588 +Curve 622 -557 601 -527 +Curve 579 -494 550 -466 +Curve 445 -374 310 -362 +Curve 187 -358 63 -354 +Curve 57 -354 51 -354 +Curve -12 -358 -74 -362 +<-------EndPath +Path -1 2 1 -74 -362 +Curve -94 -364 -113 -366 +<-------EndPath +Path -1 1 1 -113 -366 +Curve -128 -368 -142 -369 +Curve -156 -368 -170 -366 +Curve -184 -365 -194 -354 +Curve -203 -347 -205 -335 +Curve -205 -321 -205 -306 +Curve -202 -295 -198 -283 +Curve -191 -268 -183 -252 +<-------EndPath +Path -1 0 1 -183 -252 +Curve -180 -247 -177 -242 +Curve -159 -218 -141 -193 +<-------EndPath +Path -1 2 1 -141 -193 +Curve -131 -170 -120 -147 +Curve -96 -80 -99 8 +<-------EndPath +Path -1 0 1 -99 8 +Curve -99 15 -99 21 +Curve -104 60 -109 98 +Curve -111 110 -113 122 +Curve -114 125 -115 128 +Curve -118 144 -121 159 +Curve -128 197 -135 234 +Curve -135 235 -135 235 +<-------EndPath +Path -1 2 1 -135 235 +Curve -136 237 -136 239 +Curve -142 270 -155 296 +<-------EndPath +Path -1 4 1 -155 296 +Curve -161 311 -166 326 +<-------EndPath +Path -1 4 0 -166 326 +Curve -182 378 -177 436 +Curve -172 483 -167 530 +Curve -210 534 -249 517 +Curve -299 495 -349 472 +Curve -351 471 -352 470 +Curve -364 465 -376 459 +Curve -378 459 -379 458 +Curve -384 456 -388 453 +<-------EndPath +Path -1 2 0 -388 453 +Curve -428 472 -468 491 +Curve -490 500 -512 508 +Curve -566 527 -621 542 +Curve -639 546 -656 550 +Curve -672 554 -687 557 +Curve -726 565 -765 572 +Curve -757 615 -754 660 +Curve -750 719 -755 777 +<-------EndPath +Path -1 -1 0 -755 777 +Curve -757 793 -758 809 +Curve -759 816 -759 822 +Curve -761 821 -762 819 +<-------EndPath +Path -1 3 0 -762 819 +Curve -765 839 -767 859 +Curve -774 907 -826 970 +Curve -878 1033 -928 1061 +<-------EndPath +Path -1 -1 0 -928 1061 +Curve -961 1083 -993 1105 +Curve -970 1075 -947 1044 +<-------EndPath +Path -1 3 0 -947 1044 +Curve -913 996 -878 948 +Curve -836 894 -793 840 +Curve -779 824 -765 807 +<-------EndPath +Path -1 -1 0 -765 807 +Curve -768 792 -770 776 +<-------EndPath +Path -1 2 0 -770 776 +Curve -781 703 -796 654 +Curve -809 618 -821 582 +Curve -843 586 -864 589 +<-------EndPath +Path -1 2 -1 -864 589 +Curve -870 587 -875 585 +<-------EndPath +Path -1 2 0 -875 585 +Curve -913 646 -943 714 +Curve -974 782 -1016 848 +Curve -1036 876 -1056 904 +Curve -1084 938 -1112 972 +Curve -1119 979 -1125 986 +<-------EndPath +Path -1 -1 0 -1125 986 +Curve -1128 998 -1130 1009 +<-------EndPath +Path -1 3 0 -1130 1009 +Curve -1145 1061 -1166 1109 +Curve -1177 1130 -1187 1150 +Curve -1208 1185 -1257 1193 +Curve -1353 1209 -1449 1190 +Curve -1493 1184 -1537 1177 +Curve -1470 1148 -1391 1126 +Curve -1314 1104 -1238 1108 +Curve -1187 1056 -1136 1004 +<-------EndPath +Path -1 -1 0 -1136 1004 +Curve -1137 1004 -1137 1004 +Curve -1133 997 -1129 990 +<-------EndPath +Path -1 2 0 -1129 990 +Curve -1128 988 -1126 986 +Curve -1099 938 -1079 887 +Curve -1055 828 -1030 768 +Curve -1006 716 -982 664 +Curve -955 609 -917 563 +Curve -915 561 -912 559 +Curve -888 539 -848 515 +Curve -858 489 -907 398 +Curve -956 307 -890 318 +Curve -874 322 -858 326 +<-------EndPath +Path -1 4 0 -858 326 +Curve -807 318 -782 272 +Curve -775 259 -768 246 +Curve -761 233 -753 220 +<-------EndPath +Path -1 -1 1 -753 220 +Curve -753 218 -753 216 +Curve -753 215 -752 214 +Curve -752 212 -751 210 +Curve -751 210 -750 210 +<-------EndPath +Path -1 1 1 -750 210 +Curve -755 177 -751 139 +Curve -748 121 -745 103 +<-------EndPath +Path -1 0 1 -745 103 +Curve -744 100 -743 96 +Curve -743 95 -743 94 +Curve -742 90 -741 85 +Curve -740 79 -739 73 +Curve -735 55 -730 36 +Curve -729 31 -728 26 +Curve -726 18 -723 10 +Curve -706 -45 -674 -91 +Curve -657 -111 -640 -131 +<-------EndPath +Path -1 1 1 -640 -131 +Curve -610 -157 -580 -182 +Curve -594 -174 -607 -166 +Curve -576 -190 -544 -213 +Curve -513 -236 -481 -258 +<-------EndPath +Path -1 0 1 -481 -258 +Curve -450 -278 -415 -294 +<-------EndPath +Path -1 1 1 -415 -294 +Curve -409 -298 -402 -301 +Curve -395 -305 -387 -308 +Curve -351 -323 -333 -352 +Curve -328 -363 -323 -373 +Curve -324 -381 -325 -389 +Curve -345 -420 -377 -436 +Curve -385 -441 -393 -445 +<-------EndPath +Path -1 1 0 -393 -445 +Curve -439 -465 -485 -485 +Curve -514 -497 -544 -512 +Curve -578 -531 -612 -549 +Curve -641 -567 -670 -585 +Curve -697 -605 -723 -624 +Curve -748 -647 -773 -670 +Curve -795 -694 -816 -718 +Curve -845 -758 -832 -803 +<-------EndPath +Path -1 -1 0 -832 -803 +Curve -905 -859 -807 -861 +<-------EndPath +Path -1 1 0 -807 -861 +Curve -805 -864 -803 -866 +Curve -743 -939 -664 -981 +<-------EndPath +Path -1 -1 0 -664 -981 +Curve -717 -1018 -788 -1032 +Curve -855 -1046 -923 -1030 +Curve -992 -1015 -1055 -983 +Curve -1112 -953 -1162 -912 +Curve -1211 -873 -1243 -818 +Curve -1273 -768 -1282 -717 +<-------EndPath +Path 2 2 0 548 -739 +Curve 542 -738 536 -737 +<-------EndPath +Path 2 2 0 544 -632 +Curve 582 -610 583 -593 +Curve 583 -577 548 -566 +<-------EndPath +Path 2 1 -1 219 -975 +Curve 217 -970 215 -965 +Curve 271 -902 327 -838 +Curve 382 -769 399 -688 +Curve 419 -591 371 -527 +Curve 328 -470 252 -428 +Curve 204 -402 135 -401 +Curve 42 -395 -51 -389 +Curve -81 -385 -111 -381 +Curve -112 -374 -113 -366 +<-------EndPath +Path -1 -1 1 17 23 +Curve 13 29 9 34 +<-------EndPath +Path -1 -1 0 -487 -1037 +Curve -489 -1042 -490 -1047 +Curve -510 -1112 -544 -1167 +Curve -577 -1218 -625 -1259 +Curve -679 -1307 -741 -1346 +Curve -797 -1381 -862 -1396 +Curve -930 -1399 -998 -1401 +Curve -1065 -1391 -1126 -1364 +Curve -1157 -1348 -1187 -1332 +<-------EndPath +Path -1 -1 0 -1305 -1074 +Curve -1300 -1094 -1284 -1109 +Curve -1233 -1160 -1166 -1184 +Curve -1157 -1188 -1147 -1191 +Curve -1091 -1206 -1035 -1221 +Curve -968 -1235 -901 -1220 +Curve -831 -1205 -767 -1173 +Curve -711 -1146 -662 -1108 +Curve -625 -1078 -596 -1040 +Curve -595 -1039 -593 -1037 +Curve -586 -1026 -578 -1015 +<-------EndPath +Path -1 1 0 -578 -1015 +Curve -571 -1017 -563 -1018 +Curve -525 -1028 -487 -1037 +<-------EndPath +Path -1 1 0 -832 -803 +Curve -830 -813 -827 -822 +Curve -817 -842 -807 -861 +<-------EndPath +Path 0 0 1 -587 -69 +Curve -555 -49 -515 -48 +<-------EndPath +Path 0 1 1 -481 -258 +Curve -465 -211 -510 -168 +Curve -550 -132 -596 -128 +Curve -618 -130 -640 -131 +<-------EndPath +Path 1 2 -1 -231 -232 +Curve -232 -233 -232 -234 +Curve -241 -253 -242 -277 +Curve -240 -294 -238 -311 +Curve -233 -330 -219 -339 +Curve -217 -337 -215 -335 +Curve -214 -333 -213 -331 +Curve -209 -317 -211 -301 +Curve -211 -300 -211 -298 +Curve -207 -292 -203 -286 +Curve -197 -266 -203 -245 +Curve -204 -243 -204 -241 +Curve -209 -239 -213 -236 +Curve -215 -234 -216 -232 +Curve -217 -231 -218 -229 +Curve -219 -227 -220 -225 +Curve -222 -223 -224 -221 +Curve -227 -226 -230 -230 +<-------EndPath +Path 1 2 2 -230 -230 +Curve -231 -231 -231 -232 +<-------EndPath +Path 0 1 1 -183 -252 +Curve -216 -238 -241 -195 +Curve -267 -153 -321 -148 +Curve -376 -144 -400 -168 +Curve -452 -222 -415 -294 +<-------EndPath +Path 0 0 1 -383 -28 +Curve -346 -11 -304 -12 +<-------EndPath +Path 0 1 1 -162 7 +Curve -203 -10 -216 -45 +Curve -225 -68 -223 -97 +Curve -220 -132 -204 -154 +Curve -203 -156 -202 -157 +<-------EndPath +Path 0 2 1 -202 -157 +Curve -182 -184 -141 -193 +<-------EndPath +Path 2 1 -1 -202 -157 +Curve -199 -154 -196 -150 +Curve -188 -139 -180 -127 +Curve -152 -77 -155 -5 +Curve -159 1 -162 7 +<-------EndPath +Path 2 0 1 -162 7 +Curve -160 8 -157 9 +Curve -128 9 -99 8 +<-------EndPath +Path 2 2 1 -168 -135 +Curve -144 -141 -120 -147 +<-------EndPath +Path -1 1 0 -664 -981 +Curve -624 -1003 -578 -1015 +<-------EndPath +Path 0 2 1 -222 160 +Curve -194 181 -166 201 +Curve -149 215 -135 235 +<-------EndPath +Path 2 1 -1 -222 160 +Curve -226 165 -230 170 +Curve -247 223 -304 235 +<-------EndPath +Path 2 4 1 -304 235 +Curve -291 240 -278 244 +Curve -211 267 -165 303 +<-------EndPath +Path 2 4 -1 -165 303 +Curve -163 305 -161 306 +<-------EndPath +Path 2 4 1 -161 306 +Curve -158 301 -155 296 +<-------EndPath +Path 4 1 2 -304 235 +Curve -309 234 -313 232 +<-------EndPath +Path 4 1 1 -313 232 +Curve -364 218 -415 210 +Curve -475 203 -534 195 +Curve -541 195 -548 194 +Curve -613 197 -678 200 +Curve -714 205 -750 210 +<-------EndPath +Path 4 -1 1 -750 210 +Curve -751 213 -751 215 +<-------EndPath +Path 4 -1 -1 -751 215 +Curve -752 217 -752 218 +Curve -754 223 -755 227 +<-------EndPath +Path 4 -1 1 -755 227 +Curve -754 224 -753 220 +<-------EndPath +Path -1 -1 0 -753 220 +Curve -753 219 -752 218 +<-------EndPath +Path 4 4 0 -206 364 +Curve -249 405 -292 432 +<-------EndPath +Path 1 1 1 -549 139 +Curve -539 143 -528 147 +<-------EndPath +Path 0 1 1 -745 103 +Curve -739 101 -733 98 +Curve -582 30 -416 74 +Curve -310 102 -222 160 +<-------EndPath +Path -1 -1 1 -753 216 +Curve -752 216 -751 215 +<-------EndPath +Path 4 5 0 -690 359 +Curve -671 360 -651 361 +<-------EndPath +Path 4 2 0 -651 361 +Curve -645 362 -638 363 +Curve -604 371 -569 379 +Curve -546 385 -524 394 +Curve -514 398 -504 402 +Curve -483 412 -461 421 +Curve -425 437 -388 453 +<-------EndPath +Path 2 5 0 -651 361 +Curve -652 363 -637 370 +Curve -632 372 -626 374 +Curve -658 367 -690 359 +<-------EndPath +Path 2 4 0 -690 359 +Curve -736 350 -781 341 +Curve -788 340 -795 339 +Curve -827 333 -858 326 +<-------EndPath +Path 2 -1 0 -810 432 +Curve -770 446 -723 449 +Curve -699 450 -674 451 +<-------EndPath +Path 2 5 0 -674 451 +Curve -674 451 -673 450 +<-------EndPath +Path 2 2 0 -673 450 +Curve -666 447 -659 444 +Curve -648 440 -636 435 +Curve -609 425 -582 414 +Curve -555 405 -527 395 +Curve -526 395 -524 394 +<-------EndPath +Path 2 5 0 -673 450 +Curve -673 451 -673 451 +Curve -674 451 -674 451 +<-------EndPath +Path 2 -1 0 -674 451 +Curve -729 474 -784 497 +<-------EndPath +Path 2 2 0 -784 497 +Curve -782 504 -780 511 +Curve -771 541 -765 572 +<-------EndPath +Path -1 3 0 -765 807 +Curve -764 811 -763 814 +<-------EndPath +Path -1 -1 0 -763 814 +Curve -761 807 -759 800 +Curve -762 804 -765 807 +<-------EndPath +Path -1 3 0 -763 814 +Curve -763 817 -762 819 +<-------EndPath +Path -1 -1 0 -758 809 +Curve -759 814 -759 819 +Curve -759 821 -759 822 +<-------EndPath +Path 2 -1 -1 -770 776 +Curve -763 777 -755 777 +<-------EndPath +Path -1 2 0 -810 432 +Curve -794 463 -784 497 +<-------EndPath +Path -1 -1 0 -815 107 +Curve -819 114 -823 121 +<-------EndPath +Path 2 2 0 -849 370 +Curve -843 380 -836 389 +Curve -834 393 -831 396 +Curve -827 403 -823 409 +Curve -817 421 -810 432 +<-------EndPath +Path 2 2 0 -848 515 +Curve -835 549 -821 582 +<-------EndPath +Path 3 -1 -1 -947 1044 +Curve -938 1053 -928 1061 +<-------EndPath +Path 3 -1 0 -1130 1009 +Curve -1133 1007 -1136 1004 +<-------EndPath +Path -1 2 0 -1125 986 +Curve -1127 988 -1129 990 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 -2883 -474 +Curve -2871 -520 -2858 -565 +Curve -2831 -639 -2777 -696 +Curve -2734 -742 -2681 -774 +Curve -2628 -806 -2569 -821 +Curve -2507 -835 -2445 -848 +Curve -2369 -853 -2292 -858 +Curve -2217 -853 -2144 -827 +Curve -2072 -801 -2010 -754 +<-------EndPath +Path -1 1 0 -2010 -754 +Curve -2003 -763 -1996 -771 +Curve -1966 -808 -1893 -864 +Curve -1869 -882 -1845 -899 +Curve -1809 -924 -1773 -948 +Curve -1725 -974 -1676 -1000 +Curve -1609 -1030 -1541 -1059 +Curve -1527 -1066 -1513 -1073 +Curve -1479 -1086 -1445 -1099 +Curve -1393 -1111 -1341 -1123 +Curve -1308 -1129 -1274 -1134 +<-------EndPath +Path -1 0 0 -1274 -1134 +Curve -1199 -1142 -1124 -1149 +<-------EndPath +Path -1 -1 0 -1124 -1149 +Curve -1124 -1154 -1123 -1159 +Curve -1120 -1232 -1098 -1299 +Curve -1078 -1361 -1038 -1417 +Curve -994 -1481 -939 -1538 +Curve -890 -1589 -825 -1622 +Curve -760 -1658 -685 -1663 +Curve -614 -1660 -542 -1657 +Curve -506 -1648 -469 -1639 +<-------EndPath +Path -1 -1 0 -2081 -653 +Curve -2085 -655 -2089 -656 +Curve -2095 -658 -2101 -660 +Curve -2106 -662 -2110 -663 +Curve -2168 -674 -2225 -684 +Curve -2298 -682 -2371 -679 +Curve -2439 -669 -2500 -643 +Curve -2567 -615 -2625 -573 +Curve -2674 -536 -2718 -491 +Curve -2762 -449 -2795 -400 +Curve -2798 -397 -2800 -393 +Curve -2841 -334 -2866 -265 +Curve -2883 -221 -2874 -186 +<-------EndPath +Path -1 -1 0 -2128 -567 +Curve -2157 -562 -2186 -556 +Curve -2221 -547 -2256 -538 +Curve -2330 -512 -2397 -475 +Curve -2463 -440 -2509 -378 +Curve -2556 -317 -2593 -247 +Curve -2628 -183 -2620 -108 +Curve -2612 -34 -2590 24 +<-------EndPath +Path 1 -1 0 -2010 -754 +Curve -2046 -704 -2081 -653 +Curve -2082 -652 -2082 -651 +Curve -2091 -638 -2099 -624 +Curve -2114 -596 -2128 -567 +<-------EndPath +Path 1 1 0 -2128 -567 +Curve -2122 -568 -2115 -568 +<-------EndPath +Path -1 1 0 -1273 -269 +Curve -1261 -288 -1248 -306 +Curve -1236 -333 -1248 -356 +Curve -1250 -357 -1252 -358 +Curve -1267 -361 -1281 -364 +Curve -1296 -362 -1310 -360 +Curve -1325 -355 -1340 -349 +Curve -1360 -342 -1379 -335 +Curve -1446 -318 -1508 -294 +Curve -1513 -293 -1517 -292 +Curve -1519 -292 -1520 -291 +Curve -1621 -262 -1724 -244 +Curve -1753 -240 -1781 -235 +Curve -1926 -212 -2059 -281 +Curve -2094 -306 -2129 -331 +Curve -2159 -357 -2167 -390 +Curve -2168 -392 -2168 -394 +Curve -2169 -397 -2170 -399 +Curve -2176 -428 -2166 -460 +Curve -2153 -500 -2140 -540 +Curve -2134 -554 -2128 -567 +<-------EndPath +Path 1 1 0 -2096 -456 +Curve -2130 -423 -2126 -405 +Curve -2123 -388 -2083 -386 +<-------EndPath +Path -1 -1 0 -278 -1401 +Curve -294 -1417 -310 -1432 +Curve -377 -1472 -453 -1480 +Curve -464 -1481 -474 -1481 +Curve -537 -1483 -599 -1484 +Curve -674 -1482 -739 -1448 +Curve -809 -1414 -867 -1364 +Curve -919 -1321 -960 -1268 +Curve -990 -1227 -1011 -1180 +Curve -1012 -1178 -1013 -1176 +Curve -1018 -1163 -1023 -1149 +<-------EndPath +Path -1 0 0 -1023 -1149 +Curve -974 -1143 -924 -1137 +<-------EndPath +Path -1 -1 0 -924 -1137 +Curve -879 -1189 -808 -1222 +Curve -742 -1254 -666 -1255 +Curve -591 -1248 -516 -1240 +Curve -449 -1224 -386 -1194 +Curve -325 -1167 -276 -1118 +Curve -233 -1073 -210 -1021 +<-------EndPath +Path 0 -1 0 -743 -1048 +Curve -746 -1050 -749 -1052 +Curve -831 -1113 -924 -1137 +<-------EndPath +Path 0 0 0 -702 -994 +Curve -708 -1003 -713 -1012 +Curve -725 -1032 -743 -1048 +<-------EndPath +Path -1 0 0 -743 -1048 +Curve -640 -1071 -702 -994 +Curve -677 -950 -697 -901 +Curve -710 -869 -729 -839 +Curve -749 -809 -769 -778 +Curve -792 -751 -815 -723 +Curve -841 -697 -866 -671 +Curve -897 -643 -927 -615 +Curve -955 -593 -982 -571 +Curve -1025 -538 -1068 -505 +Curve -1075 -498 -1082 -491 +Curve -1111 -466 -1124 -429 +Curve -1124 -423 -1123 -416 +Curve -1115 -397 -1100 -383 +Curve -1098 -381 -1096 -379 +<-------EndPath +Path -1 -1 0 -1096 -379 +Curve -1075 -369 -1054 -359 +<-------EndPath +Path -1 0 0 -1054 -359 +Curve -999 -330 -949 -291 +<-------EndPath +Path -1 4 0 -949 -291 +Curve -929 -275 -909 -258 +Curve -840 -198 -789 -122 +Curve -780 -108 -771 -94 +Curve -744 -50 -724 7 +<-------EndPath +Path -1 0 0 -724 7 +Curve -709 52 -697 127 +<-------EndPath +Path -1 -1 0 -697 127 +Curve -621 185 -545 243 +<-------EndPath +Path 0 1 -1 -1274 -1134 +Curve -1273 -1115 -1271 -1096 +Curve -1240 -1098 -1209 -1099 +Curve -1050 -1105 -905 -1051 +Curve -740 -990 -850 -832 +Curve -938 -705 -1054 -619 +Curve -1162 -539 -1159 -387 +Curve -1159 -386 -1159 -385 +Curve -1157 -323 -1103 -295 +Curve -1041 -263 -985 -218 +<-------EndPath +Path 0 -1 -1 -985 -218 +Curve -977 -212 -968 -205 +<-------EndPath +Path 0 4 0 -968 -205 +Curve -943 -230 -949 -291 +<-------EndPath +Path 0 -1 0 -1023 -1149 +Curve -1031 -1149 -1039 -1149 +Curve -1082 -1149 -1124 -1149 +<-------EndPath +Path 4 1 -1 -1264 -263 +Curve -1269 -266 -1273 -269 +<-------EndPath +Path 4 -1 0 -1273 -269 +Curve -1283 -257 -1292 -244 +Curve -1316 -213 -1330 -178 +Curve -1341 -144 -1352 -110 +Curve -1354 -101 -1355 -91 +<-------EndPath +Path 4 1 0 -1355 -91 +Curve -1348 -94 -1341 -96 +Curve -1339 -97 -1337 -97 +Curve -1256 -211 -1209 -204 +Curve -1182 -200 -1166 -153 +Curve -1126 -27 -1218 21 +Curve -1310 69 -1364 -53 +<-------EndPath +Path 4 -1 0 -1364 -53 +Curve -1370 -19 -1375 15 +Curve -1380 98 -1385 181 +Curve -1385 182 -1385 182 +<-------EndPath +Path 4 1 -1 -1385 182 +Curve -1380 182 -1375 182 +<-------EndPath +Path 4 1 0 -1375 182 +Curve -1274 214 -1174 203 +Curve -1075 191 -966 161 +Curve -884 139 -787 62 +<-------EndPath +Path 4 0 0 -787 62 +Curve -756 35 -724 7 +<-------EndPath +Path -1 1 0 -1364 -53 +Curve -1363 -57 -1361 -61 +Curve -1360 -64 -1359 -67 +Curve -1357 -79 -1355 -91 +<-------EndPath +Path -1 -1 0 -1355 -91 +Curve -1427 -65 -1495 -25 +Curve -1604 41 -1708 114 +Curve -1878 232 -1674 253 +Curve -1539 266 -1409 301 +Curve -1396 305 -1382 308 +<-------EndPath +Path -1 1 0 -1382 308 +Curve -1388 255 -1386 201 +Curve -1386 192 -1385 182 +<-------EndPath +Path 1 1 0 -1337 -97 +Curve -1296 -109 -1254 -120 +<-------EndPath +Path 0 -1 0 -1054 -359 +Curve -1062 -362 -1069 -364 +Curve -1083 -372 -1096 -379 +<-------EndPath +Path 4 1 0 -1008 -187 +Curve -1076 -181 -1133 -218 +Curve -1160 -236 -1192 -247 +Curve -1193 -247 -1193 -247 +Curve -1195 -248 -1196 -248 +Curve -1230 -256 -1264 -263 +<-------EndPath +Path -1 1 -1 -985 -218 +Curve -997 -203 -1008 -187 +<-------EndPath +Path -1 4 0 -1008 -187 +Curve -983 -190 -968 -205 +<-------EndPath +Path -1 -1 0 -904 -267 +Curve -769 -270 -637 -242 +Curve -438 -199 -538 -83 +Curve -613 4 -687 90 +Curve -627 96 -566 101 +<-------EndPath +Path -1 2 0 -686 199 +Curve -685 212 -683 225 +Curve -667 371 -595 383 +Curve -642 489 -717 530 +<-------EndPath +Path -1 0 0 -717 530 +Curve -717 587 -725 645 +Curve -735 708 -745 771 +Curve -754 820 -754 870 +Curve -752 877 -750 883 +Curve -740 928 -729 972 +Curve -712 1043 -717 1116 +Curve -720 1162 -723 1207 +Curve -726 1239 -728 1270 +Curve -730 1337 -731 1404 +<-------EndPath +Path -1 -1 0 -731 1404 +Curve -729 1405 -727 1406 +Curve -726 1411 -725 1415 +Curve -728 1416 -731 1416 +<-------EndPath +Path -1 3 0 -731 1416 +Curve -734 1417 -736 1417 +Curve -799 1421 -861 1424 +Curve -940 1411 -1019 1398 +Curve -1087 1383 -1154 1368 +Curve -1192 1357 -1229 1346 +Curve -1182 1328 -1131 1327 +Curve -1071 1331 -1011 1334 +Curve -994 1337 -977 1339 +Curve -908 1352 -838 1365 +Curve -807 1374 -776 1383 +Curve -755 1391 -735 1402 +<-------EndPath +Path -1 0 0 -735 1402 +Curve -757 1303 -779 1203 +Curve -798 1113 -804 1014 +Curve -810 915 -816 816 +Curve -818 798 -819 779 +Curve -826 715 -842 651 +Curve -850 619 -858 587 +<-------EndPath +Path -1 2 0 -858 587 +Curve -887 586 -915 584 +<-------EndPath +Path -1 3 0 -915 584 +Curve -998 610 -1081 635 +Curve -1094 639 -1107 642 +Curve -1127 646 -1146 650 +<-------EndPath +Path -1 -1 0 -1146 650 +Curve -1150 658 -1153 665 +<-------EndPath +Path -1 0 0 -1153 665 +Curve -1219 862 -1252 924 +Curve -1267 954 -1281 983 +Curve -1271 1127 -1364 1261 +Curve -1424 1347 -1484 1432 +Curve -1436 1326 -1407 1245 +Curve -1398 1215 -1389 1185 +Curve -1351 1046 -1329 904 +Curve -1306 782 -1283 660 +<-------EndPath +Path -1 -1 0 -1283 660 +Curve -1286 660 -1288 659 +<-------EndPath +Path -1 3 0 -1288 659 +Curve -1368 655 -1438 625 +Curve -1434 621 -1430 616 +<-------EndPath +Path -1 2 0 -1430 616 +Curve -1355 518 -1344 474 +<-------EndPath +Path -1 -1 0 -1344 474 +Curve -1351 445 -1358 415 +<-------EndPath +Path -1 2 0 -1358 415 +Curve -1363 398 -1368 380 +<-------EndPath +Path -1 -1 0 -1368 380 +Curve -1371 384 -1374 388 +Curve -1392 413 -1410 437 +<-------EndPath +Path 0 -1 0 -686 199 +Curve -692 163 -697 127 +<-------EndPath +Path 0 1 -1 -787 62 +Curve -783 97 -779 131 +Curve -773 271 -876 351 +<-------EndPath +Path 0 2 0 -876 351 +Curve -778 317 -686 199 +<-------EndPath +Path -1 -1 0 -687 104 +Curve -632 144 -560 160 +<-------EndPath +Path 0 2 0 -717 530 +Curve -741 541 -764 551 +Curve -812 568 -859 584 +Curve -859 585 -858 586 +<-------EndPath +Path 0 -1 0 -858 586 +Curve -857 587 -856 587 +Curve -857 587 -858 587 +<-------EndPath +Path 2 -1 0 -858 587 +Curve -858 587 -858 586 +<-------EndPath +Path 2 1 0 -876 351 +Curve -888 354 -899 357 +Curve -1009 383 -1121 378 +Curve -1236 366 -1351 353 +<-------EndPath +Path 2 -1 0 -1351 353 +Curve -1360 367 -1368 380 +<-------EndPath +Path -1 -1 0 -1368 380 +Curve -1372 367 -1376 353 +Curve -1410 380 -1443 407 +<-------EndPath +Path -1 -1 0 -1376 353 +Curve -1374 351 -1372 349 +Curve -1375 349 -1377 348 +Curve -1377 351 -1376 353 +<-------EndPath +Path -1 -1 0 -1372 349 +Curve -1357 334 -1341 319 +Curve -1360 325 -1379 331 +Curve -1378 340 -1377 348 +<-------EndPath +Path -1 1 0 -1351 353 +Curve -1345 336 -1339 318 +<-------EndPath +Path -1 -1 0 -1339 318 +Curve -1340 319 -1341 319 +<-------EndPath +Path 1 -1 0 -1382 308 +Curve -1361 313 -1339 318 +<-------EndPath +Path -1 -1 0 -1382 308 +Curve -1381 320 -1379 331 +Curve -1462 358 -1541 394 +<-------EndPath +Path -1 -1 0 -1372 349 +Curve -1362 351 -1351 353 +<-------EndPath +Path 2 -1 0 -1358 415 +Curve -1351 443 -1343 470 +Curve -1344 472 -1344 474 +<-------EndPath +Path 0 -1 0 -1279 628 +Curve -1281 644 -1283 660 +<-------EndPath +Path 3 -1 0 -1288 659 +Curve -1284 644 -1279 628 +<-------EndPath +Path 3 0 0 -1279 628 +Curve -1269 598 -1259 568 +<-------EndPath +Path 3 0 -1 -1259 568 +Curve -1256 562 -1252 556 +<-------EndPath +Path 3 2 0 -1252 556 +Curve -1349 561 -1430 616 +<-------EndPath +Path 0 0 0 -1281 983 +Curve -1283 972 -1284 961 +<-------EndPath +Path 3 2 0 -915 584 +Curve -955 580 -994 576 +Curve -1057 569 -1120 562 +<-------EndPath +Path 3 0 0 -1120 562 +Curve -1130 593 -1139 624 +<-------EndPath +Path 3 -1 0 -1139 624 +Curve -1143 637 -1146 650 +<-------EndPath +Path -1 -1 0 -1146 650 +Curve -1147 650 -1148 650 +<-------EndPath +Path -1 0 0 -1148 650 +Curve -1151 658 -1153 665 +<-------EndPath +Path 2 0 0 -1252 556 +Curve -1231 556 -1210 556 +Curve -1165 559 -1120 562 +<-------EndPath +Path -1 0 0 -1139 624 +Curve -1144 637 -1148 650 +<-------EndPath +Path -1 0 0 -731 1404 +Curve -733 1403 -735 1402 +<-------EndPath +Path -1 3 0 -735 1402 +Curve -733 1409 -731 1416 +<-------EndPath +Path -1 -1 0 -731 1416 +Curve -731 1410 -731 1404 +<-------EndPath +Path 3 -1 0 -1796 1387 +Curve -1949 1375 -2096 1407 +Curve -2131 1415 -2160 1432 +Curve -2055 1472 -1930 1478 +Curve -1793 1474 -1655 1470 +Curve -1569 1457 -1482 1444 +Curve -1565 1420 -1647 1406 +Curve -1722 1397 -1796 1387 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 423 -1034 +Curve 424 -1039 424 -1044 +Curve 427 -1116 449 -1182 +Curve 469 -1242 509 -1297 +Curve 553 -1360 608 -1416 +Curve 657 -1466 722 -1498 +Curve 787 -1533 862 -1538 +Curve 934 -1535 1005 -1532 +Curve 1042 -1524 1078 -1515 +<-------EndPath +Path -1 -1 0 623 -1022 +Curve 668 -1074 739 -1106 +Curve 805 -1137 881 -1138 +Curve 956 -1131 1031 -1124 +Curve 1098 -1108 1161 -1079 +Curve 1222 -1052 1271 -1004 +Curve 1314 -960 1337 -909 +<-------EndPath +Path -1 -1 0 1269 -1281 +Curve 1257 -1300 1237 -1312 +Curve 1170 -1351 1094 -1359 +Curve 1084 -1360 1073 -1360 +Curve 1011 -1362 948 -1363 +Curve 873 -1360 808 -1327 +Curve 738 -1294 680 -1245 +Curve 628 -1203 587 -1151 +Curve 557 -1111 536 -1064 +Curve 535 -1063 534 -1061 +Curve 529 -1048 524 -1034 +<-------EndPath +Path -1 0 0 524 -1034 +Curve 574 -1028 623 -1022 +Curve 716 -999 798 -939 +Curve 801 -937 804 -935 +Curve 907 -958 845 -882 +Curve 870 -839 850 -791 +Curve 834 -761 818 -730 +Curve 798 -700 778 -670 +Curve 755 -643 732 -616 +Curve 707 -591 681 -565 +Curve 651 -538 620 -510 +Curve 593 -489 565 -467 +Curve 522 -435 479 -402 +Curve 472 -396 465 -389 +Curve 436 -364 423 -328 +Curve 424 -322 424 -315 +Curve 432 -296 447 -283 +Curve 449 -281 451 -279 +<-------EndPath +Path -1 -1 0 451 -279 +Curve 472 -269 493 -259 +<-------EndPath +Path -1 0 0 493 -259 +Curve 546 -226 598 -192 +<-------EndPath +Path -1 2 0 598 -192 +Curve 618 -176 638 -160 +Curve 707 -101 758 -26 +Curve 767 -13 776 1 +Curve 796 41 816 81 +Curve 820 91 823 100 +<-------EndPath +Path -1 0 0 823 100 +Curve 838 145 850 220 +<-------EndPath +Path -1 -1 0 850 220 +Curve 926 278 1002 336 +<-------EndPath +Path 1 -1 0 273 -1019 +Curve 240 -1014 206 -1009 +Curve 154 -997 102 -985 +Curve 68 -973 34 -960 +Curve 20 -953 6 -946 +Curve -62 -917 -129 -888 +Curve -178 -863 -226 -837 +Curve -262 -813 -298 -789 +Curve -322 -772 -346 -754 +Curve -419 -700 -449 -663 +Curve -456 -655 -463 -646 +Curve -499 -597 -534 -548 +Curve -535 -547 -535 -546 +Curve -544 -533 -552 -519 +Curve -567 -491 -581 -463 +<-------EndPath +Path 1 1 0 -581 -463 +Curve -575 -464 -568 -464 +<-------EndPath +Path 0 -1 0 524 -1034 +Curve 516 -1034 508 -1034 +Curve 466 -1034 423 -1034 +Curve 348 -1027 273 -1019 +<-------EndPath +Path 0 1 -1 273 -1019 +Curve 275 -1001 276 -982 +Curve 307 -984 338 -985 +Curve 497 -991 642 -938 +Curve 807 -878 697 -723 +Curve 609 -598 493 -514 +Curve 385 -435 388 -286 +Curve 388 -285 388 -284 +Curve 390 -224 444 -196 +Curve 506 -165 562 -121 +<-------EndPath +Path 0 -1 -1 562 -121 +Curve 571 -115 579 -108 +<-------EndPath +Path 0 2 0 579 -108 +Curve 604 -133 598 -192 +<-------EndPath +Path -1 1 0 274 -171 +Curve 287 -189 299 -207 +Curve 311 -233 299 -256 +Curve 297 -257 295 -258 +Curve 281 -261 266 -264 +Curve 252 -262 237 -260 +Curve 222 -255 207 -249 +Curve 188 -243 168 -236 +Curve 104 -216 39 -195 +Curve 35 -195 30 -194 +Curve 29 -193 27 -192 +Curve -74 -164 -177 -146 +Curve -206 -142 -234 -137 +Curve -379 -115 -512 -183 +Curve -547 -207 -582 -231 +Curve -612 -257 -620 -289 +Curve -621 -291 -621 -293 +Curve -622 -296 -623 -299 +Curve -629 -326 -619 -358 +Curve -606 -397 -593 -436 +Curve -587 -450 -581 -463 +<-------EndPath +Path -1 -1 0 -581 -463 +Curve -610 -458 -639 -453 +Curve -674 -444 -709 -434 +Curve -783 -409 -850 -373 +Curve -916 -339 -962 -278 +Curve -1009 -217 -1046 -149 +Curve -1081 -87 -1073 -13 +Curve -1068 38 -1055 82 +Curve -1049 100 -1043 117 +<-------EndPath +Path 2 1 0 539 -90 +Curve 471 -84 414 -120 +Curve 387 -138 355 -149 +Curve 355 -149 354 -149 +Curve 353 -150 351 -150 +Curve 317 -158 283 -165 +<-------EndPath +Path 2 1 -1 283 -165 +Curve 279 -168 274 -171 +<-------EndPath +Path 2 -1 0 274 -171 +Curve 265 -159 255 -146 +Curve 231 -116 217 -81 +Curve 206 -48 195 -14 +Curve 194 -5 192 4 +<-------EndPath +Path 2 1 0 192 4 +Curve 199 2 206 -1 +Curve 208 -2 210 -2 +Curve 291 -114 338 -107 +Curve 365 -103 381 -57 +Curve 410 32 371 81 +Curve 371 82 370 82 +Curve 354 101 329 114 +Curve 255 152 206 82 +Curve 206 82 205 81 +Curve 194 61 183 41 +<-------EndPath +Path 2 -1 0 183 41 +Curve 179 61 175 81 +Curve 175 82 175 82 +Curve 174 95 172 108 +Curve 167 191 162 274 +Curve 162 275 162 275 +<-------EndPath +Path 2 1 -1 162 275 +Curve 167 275 172 275 +<-------EndPath +Path 2 1 0 172 275 +Curve 273 307 373 296 +Curve 472 284 581 254 +Curve 663 232 760 155 +<-------EndPath +Path 2 0 0 760 155 +Curve 792 128 823 100 +<-------EndPath +Path 1 1 0 210 -2 +Curve 252 -13 293 -24 +<-------EndPath +Path 0 -1 0 493 -259 +Curve 486 -262 478 -264 +Curve 463 -270 451 -279 +<-------EndPath +Path -1 1 -1 562 -121 +Curve 551 -106 539 -90 +<-------EndPath +Path -1 2 0 539 -90 +Curve 564 -93 579 -108 +<-------EndPath +Path 0 0 0 845 -882 +Curve 840 -891 834 -900 +Curve 819 -918 804 -935 +<-------EndPath +Path -1 -1 0 643 -168 +Curve 778 -171 910 -144 +Curve 1109 -102 1009 12 +Curve 979 47 949 82 +Curve 905 133 860 183 +Curve 921 178 981 194 +<-------EndPath +Path -1 4 0 861 292 +Curve 863 305 864 318 +Curve 880 464 952 476 +Curve 905 582 830 623 +<-------EndPath +Path -1 0 0 830 623 +Curve 830 680 822 738 +Curve 812 801 802 864 +Curve 793 913 793 963 +Curve 795 970 797 976 +Curve 808 1021 818 1065 +Curve 835 1136 830 1209 +Curve 827 1255 824 1300 +Curve 822 1332 819 1363 +Curve 815 1414 816 1497 +<-------EndPath +Path -1 -1 0 816 1497 +Curve 818 1498 820 1499 +Curve 821 1504 822 1508 +Curve 819 1509 816 1509 +<-------EndPath +Path -1 3 0 816 1509 +Curve 814 1510 811 1510 +Curve 749 1514 686 1517 +Curve 607 1504 528 1491 +Curve 461 1476 393 1461 +Curve 356 1450 318 1439 +Curve 365 1421 416 1420 +Curve 476 1424 536 1427 +Curve 553 1430 570 1432 +Curve 640 1445 709 1458 +Curve 740 1467 771 1476 +Curve 792 1484 812 1495 +<-------EndPath +Path -1 0 0 812 1495 +Curve 790 1396 768 1296 +Curve 749 1206 743 1107 +Curve 737 1008 731 909 +Curve 730 891 728 872 +Curve 721 808 705 744 +Curve 697 712 689 680 +<-------EndPath +Path -1 4 0 689 680 +Curve 661 679 632 677 +<-------EndPath +Path -1 3 0 632 677 +Curve 549 703 466 728 +Curve 453 732 440 735 +Curve 421 739 401 743 +<-------EndPath +Path -1 -1 0 401 743 +Curve 398 751 394 758 +<-------EndPath +Path -1 0 0 394 758 +Curve 328 955 295 1017 +Curve 281 1047 266 1076 +Curve 276 1220 183 1354 +Curve 123 1440 63 1525 +Curve 102 1432 140 1338 +Curve 149 1308 158 1278 +Curve 196 1139 218 997 +Curve 241 875 264 753 +<-------EndPath +Path -1 -1 0 264 753 +Curve 262 753 259 752 +<-------EndPath +Path -1 3 0 259 752 +Curve 179 748 109 718 +Curve 113 714 117 709 +<-------EndPath +Path -1 4 0 117 709 +Curve 192 611 203 567 +<-------EndPath +Path -1 -1 0 203 567 +Curve 196 538 189 508 +<-------EndPath +Path -1 4 0 189 508 +Curve 184 491 179 473 +<-------EndPath +Path -1 -1 0 179 473 +Curve 176 477 173 481 +Curve 155 506 137 530 +<-------EndPath +Path -1 -1 0 860 197 +Curve 915 237 987 253 +<-------EndPath +Path -1 0 0 850 220 +Curve 856 256 861 292 +<-------EndPath +Path 4 0 0 861 292 +Curve 769 410 671 444 +<-------EndPath +Path 4 1 0 671 444 +Curve 660 447 648 450 +Curve 538 476 426 471 +Curve 311 459 196 446 +<-------EndPath +Path 4 -1 0 196 446 +Curve 188 460 179 473 +<-------EndPath +Path -1 -1 0 179 473 +Curve 175 460 171 446 +Curve 138 473 104 500 +<-------EndPath +Path 0 1 -1 760 155 +Curve 764 190 768 224 +Curve 774 364 671 444 +<-------EndPath +Path 1 -1 0 192 4 +Curve 190 16 188 28 +Curve 187 31 186 33 +Curve 185 37 183 41 +<-------EndPath +Path -1 -1 0 6 487 +Curve 85 451 168 424 +Curve 167 413 165 401 +Curve 152 398 138 394 +Curve 8 359 -127 346 +Curve -331 325 -161 207 +Curve -67 141 31 81 +Curve 42 75 52 69 +Curve 120 29 192 4 +<-------EndPath +Path 1 -1 0 162 275 +Curve 162 285 161 294 +Curve 159 348 165 401 +Curve 187 406 208 411 +Curve 202 429 196 446 +<-------EndPath +Path -1 -1 0 196 446 +Curve 186 444 175 442 +Curve 173 444 171 446 +Curve 171 444 170 441 +Curve 169 433 168 424 +Curve 187 418 206 412 +Curve 207 412 208 411 +<-------EndPath +Path -1 -1 0 170 441 +Curve 173 442 175 442 +Curve 191 427 206 412 +<-------EndPath +Path 0 3 0 288 661 +Curve 278 691 268 721 +<-------EndPath +Path 0 -1 0 268 721 +Curve 266 737 264 753 +<-------EndPath +Path 4 -1 0 189 508 +Curve 197 536 204 563 +Curve 204 565 203 567 +<-------EndPath +Path 3 0 -1 288 661 +Curve 292 655 295 649 +<-------EndPath +Path 3 4 0 295 649 +Curve 198 654 117 709 +<-------EndPath +Path 4 0 0 295 649 +Curve 316 649 337 649 +Curve 382 652 427 655 +<-------EndPath +Path 4 3 0 427 655 +Curve 490 662 553 669 +Curve 593 673 632 677 +<-------EndPath +Path 0 -1 0 394 758 +Curve 397 751 399 743 +Curve 404 730 408 717 +<-------EndPath +Path 0 3 0 408 717 +Curve 418 686 427 655 +<-------EndPath +Path -1 -1 0 399 743 +Curve 400 743 401 743 +<-------EndPath +Path -1 3 0 401 743 +Curve 405 730 408 717 +<-------EndPath +Path -1 3 0 268 721 +Curve 264 737 259 752 +<-------EndPath +Path 4 -1 0 689 680 +Curve 689 680 689 679 +<-------EndPath +Path 4 0 0 689 679 +Curve 689 678 688 677 +Curve 736 661 783 644 +Curve 807 634 830 623 +<-------EndPath +Path 0 -1 0 689 679 +Curve 690 680 691 680 +Curve 690 680 689 680 +<-------EndPath +Path 0 0 0 263 1054 +Curve 265 1065 266 1076 +<-------EndPath +Path 0 -1 0 812 1495 +Curve 814 1496 816 1497 +<-------EndPath +Path -1 -1 0 816 1497 +Curve 816 1503 816 1509 +<-------EndPath +Path 3 -1 0 816 1509 +Curve 814 1502 812 1495 +<-------EndPath +Path -1 -1 0 -1336 -372 +Curve -1324 -417 -1311 -461 +Curve -1284 -534 -1230 -589 +Curve -1187 -635 -1134 -666 +Curve -1081 -698 -1022 -713 +Curve -960 -726 -898 -739 +Curve -822 -744 -745 -749 +Curve -670 -743 -597 -718 +Curve -525 -692 -463 -646 +<-------EndPath +Path -1 -1 0 -534 -548 +Curve -538 -549 -542 -550 +Curve -548 -553 -554 -555 +Curve -559 -557 -563 -558 +Curve -618 -574 -678 -578 +Curve -751 -576 -824 -573 +Curve -892 -563 -953 -538 +Curve -1020 -510 -1078 -469 +Curve -1125 -429 -1171 -388 +Curve -1215 -348 -1248 -299 +Curve -1251 -296 -1253 -293 +Curve -1294 -235 -1319 -167 +Curve -1336 -124 -1327 -89 +<-------EndPath +Path 1 1 0 -549 -354 +Curve -583 -322 -579 -304 +Curve -576 -287 -536 -285 +<-------EndPath +Path 3 -1 0 -549 1500 +Curve -584 1508 -613 1525 +Curve -508 1565 -383 1571 +Curve -246 1567 -108 1563 +Curve -22 1550 65 1537 +Curve -18 1513 -100 1499 +Curve -175 1490 -249 1480 +Curve -402 1468 -549 1500 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 1168 -1806 +Curve 1045 -1810 922 -1814 +Curve 799 -1796 704 -1719 +Curve 686 -1703 667 -1686 +Curve 601 -1622 573 -1545 +Curve 520 -1667 576 -1774 +Curve 582 -1785 588 -1796 +Curve 638 -1891 708 -1973 +Curve 782 -2059 884 -2106 +Curve 908 -2115 932 -2124 +Curve 975 -2132 1018 -2140 +<-------EndPath +Path 1 -1 0 1121 -1437 +Curve 1090 -1445 1059 -1453 +Curve 999 -1465 939 -1477 +<-------EndPath +Path 1 0 -1 939 -1477 +Curve 946 -1474 953 -1470 +Curve 956 -1469 959 -1467 +Curve 1071 -1436 1165 -1370 +Curve 1194 -1349 1222 -1328 +<-------EndPath +Path 1 1 0 1222 -1328 +Curve 1196 -1411 1121 -1437 +<-------EndPath +Path -1 1 0 1121 -1437 +Curve 1262 -1393 1373 -1311 +Curve 1484 -1230 1506 -1179 +Curve 1528 -1128 1491 -1038 +Curve 1454 -948 1074 -821 +<-------EndPath +Path -1 1 1 1074 -821 +Curve 1049 -817 1024 -813 +<-------EndPath +Path -1 -1 1 1024 -813 +Curve 1004 -810 984 -806 +<-------EndPath +Path -1 1 1 984 -806 +Curve 925 -798 866 -789 +<-------EndPath +Path -1 0 1 866 -789 +Curve 835 -787 804 -785 +Curve 724 -788 643 -791 +<-------EndPath +Path -1 -1 1 643 -791 +Curve 611 -790 579 -788 +Curve 562 -788 542 -770 +Curve 522 -749 502 -728 +<-------EndPath +Path -1 -1 0 502 -728 +Curve 495 -718 488 -707 +Curve 486 -701 484 -695 +Curve 482 -682 480 -669 +<-------EndPath +Path -1 1 0 480 -669 +Curve 478 -651 484 -636 +Curve 500 -612 515 -587 +<-------EndPath +Path -1 4 0 515 -587 +Curve 524 -573 533 -558 +Curve 540 -549 546 -539 +Curve 553 -528 559 -516 +Curve 562 -509 564 -502 +<-------EndPath +Path -1 1 0 564 -502 +Curve 595 -417 569 -254 +Curve 563 -219 556 -183 +<-------EndPath +Path -1 0 0 556 -183 +Curve 531 -63 492 36 +<-------EndPath +Path -1 4 0 492 36 +Curve 479 67 466 97 +Curve 400 237 328 455 +<-------EndPath +Path -1 -1 0 328 455 +Curve 323 476 318 496 +<-------EndPath +Path -1 4 0 318 496 +Curve 319 521 319 546 +Curve 321 567 323 588 +Curve 339 732 412 874 +Curve 465 979 499 1089 +Curve 531 1193 546 1302 +Curve 566 1441 558 1575 +Curve 555 1611 511 1632 +<-------EndPath +Path -1 3 0 511 1632 +Curve 552 1669 751 1503 +Curve 974 1539 813 1696 +Curve 652 1852 449 1910 +Curve 246 1967 224 1686 +<-------EndPath +Path -1 3 -1 224 1686 +Curve 224 1683 223 1680 +<-------EndPath +Path -1 4 0 223 1680 +Curve 153 1694 83 1707 +Curve -33 1730 -49 1586 +Curve -61 1482 -90 1440 +Curve -106 1473 -121 1505 +Curve -198 1658 -291 1789 +Curve -308 1808 -324 1826 +Curve -350 1843 -375 1859 +Curve -419 1845 -462 1830 +Curve -485 1822 -507 1813 +<-------EndPath +Path -1 3 0 -507 1813 +Curve -442 1848 -383 1875 +Curve -319 1901 -255 1927 +Curve -234 1933 -225 1947 +Curve -222 1961 -243 2025 +Curve -285 2039 -340 2042 +Curve -366 2042 -392 2042 +Curve -459 2034 -526 2025 +Curve -705 1988 -859 1907 +Curve -1051 1806 -910 1657 +<-------EndPath +Path -1 4 0 -910 1657 +Curve -931 1636 -952 1614 +Curve -938 1591 -923 1568 +Curve -826 1434 -749 1288 +Curve -699 1191 -659 1089 +Curve -642 1041 -624 992 +Curve -575 844 -522 705 +Curve -522 695 -521 684 +Curve -515 620 -499 559 +Curve -499 558 -499 556 +Curve -499 555 -498 554 +Curve -498 553 -498 552 +Curve -498 551 -497 550 +Curve -497 549 -496 547 +Curve -496 544 -495 541 +Curve -493 534 -490 527 +Curve -489 520 -487 512 +Curve -468 422 -443 349 +Curve -396 213 -349 76 +Curve -347 69 -344 61 +<-------EndPath +Path -1 0 0 -344 61 +Curve -310 -31 -275 -122 +Curve -184 -357 -66 -468 +Curve 50 -578 148 -621 +<-------EndPath +Path -1 4 0 148 -621 +Curve 150 -622 152 -622 +Curve 191 -636 230 -649 +<-------EndPath +Path -1 0 0 230 -649 +Curve 253 -661 276 -673 +Curve 308 -695 326 -726 +<-------EndPath +Path -1 0 1 326 -726 +Curve 330 -734 334 -742 +Curve 337 -749 339 -756 +Curve 341 -766 342 -775 +Curve 345 -796 334 -818 +Curve 323 -840 304 -856 +<-------EndPath +Path -1 0 0 304 -856 +Curve 189 -888 -11 -986 +Curve -295 -1125 -279 -1231 +Curve -276 -1253 -272 -1275 +Curve -269 -1285 -266 -1295 +Curve -246 -1350 -194 -1385 +Curve -114 -1439 -38 -1461 +Curve 27 -1478 92 -1494 +Curve 122 -1500 152 -1505 +Curve 155 -1506 157 -1506 +Curve 274 -1520 390 -1533 +Curve 414 -1534 437 -1535 +Curve 465 -1536 492 -1537 +Curve 520 -1537 548 -1536 +Curve 560 -1536 572 -1535 +Curve 625 -1531 678 -1527 +Curve 720 -1519 762 -1511 +Curve 851 -1494 939 -1477 +<-------EndPath +Path 0 0 0 959 -1467 +Curve 1002 -1443 1023 -1395 +<-------EndPath +Path 1 0 -1 1222 -1328 +Curve 1328 -1309 1414 -1192 +Curve 1500 -1075 1358 -987 +Curve 1215 -899 1068 -863 +Curve 930 -829 866 -789 +<-------EndPath +Path -1 -1 0 1043 -1933 +Curve 919 -1974 808 -1912 +Curve 708 -1856 630 -1771 +Curve 621 -1759 612 -1747 +Curve 546 -1659 573 -1545 +<-------EndPath +Path 0 0 0 157 -1506 +Curve 185 -1485 191 -1453 +Curve 194 -1432 189 -1407 +<-------EndPath +Path 0 0 0 390 -1533 +Curve 405 -1518 420 -1503 +Curve 434 -1482 438 -1453 +<-------EndPath +Path -1 0 -1 643 -791 +Curve 619 -793 594 -795 +Curve 527 -777 489 -726 +Curve 484 -719 479 -711 +Curve 476 -706 473 -701 +Curve 468 -690 462 -678 +<-------EndPath +Path -1 1 -1 462 -678 +Curve 471 -674 480 -669 +<-------EndPath +Path 1 0 -1 462 -678 +Curve 461 -675 460 -671 +Curve 430 -590 466 -503 +Curve 481 -468 495 -432 +<-------EndPath +Path 1 4 0 495 -432 +Curve 504 -487 512 -542 +Curve 513 -551 514 -559 +Curve 515 -573 515 -587 +<-------EndPath +Path 4 0 -1 148 -621 +Curve 151 -615 153 -609 +<-------EndPath +Path 4 0 0 153 -609 +Curve 170 -489 140 -376 +Curve 108 -260 62 -151 +Curve 58 -142 53 -132 +Curve 5 -27 -75 54 +Curve -174 154 -299 95 +Curve -335 78 -335 65 +<-------EndPath +Path 4 0 -1 -335 65 +Curve -340 63 -344 61 +<-------EndPath +Path 4 0 0 495 -432 +Curve 492 -421 489 -409 +Curve 475 -355 461 -300 +Curve 461 -300 460 -299 +Curve 443 -227 426 -155 +Curve 416 -111 393 -103 +Curve 354 -92 314 -81 +Curve 225 -59 134 -54 +Curve 142 -70 149 -86 +Curve 177 -138 204 -190 +Curve 265 -297 274 -421 +Curve 282 -551 230 -649 +<-------EndPath +Path 1 4 0 564 -502 +Curve 557 -462 550 -422 +Curve 550 -421 550 -420 +Curve 548 -409 546 -397 +Curve 538 -361 530 -324 +<-------EndPath +Path 1 0 -1 530 -324 +Curve 536 -303 542 -282 +Curve 555 -232 556 -183 +<-------EndPath +Path 0 4 0 530 -324 +Curve 526 -305 522 -286 +Curve 522 -286 521 -285 +Curve 492 -161 479 -35 +Curve 472 30 492 36 +<-------EndPath +Path 1 -1 0 984 -806 +Curve 988 -807 992 -808 +Curve 1008 -811 1024 -813 +<-------EndPath +Path 0 0 0 762 -1511 +Curve 801 -1471 812 -1414 +<-------EndPath +Path -1 4 0 328 455 +Curve 323 471 318 486 +Curve 318 487 318 487 +Curve 318 492 318 496 +<-------EndPath +Path 4 4 0 -90 1440 +Curve -49 1346 -18 1248 +Curve -12 1226 -5 1204 +Curve 11 1147 27 1089 +Curve 55 994 83 899 +Curve 98 845 112 790 +Curve 124 738 136 685 +Curve 143 659 149 633 +Curve 149 590 148 547 +<-------EndPath +Path 4 4 0 88 1212 +Curve 69 1241 63 1274 +Curve 56 1306 61 1342 +<-------EndPath +Path 2 3 -1 375 1656 +Curve 375 1660 375 1664 +<-------EndPath +Path 2 3 0 375 1664 +Curve 393 1661 411 1658 +<-------EndPath +Path 2 4 0 411 1658 +Curve 393 1657 375 1656 +<-------EndPath +Path 3 4 0 375 1656 +Curve 299 1668 223 1680 +<-------EndPath +Path 3 4 0 511 1632 +Curve 494 1638 476 1644 +Curve 451 1650 426 1655 +Curve 419 1657 411 1658 +<-------EndPath +Path 0 0 0 -184 -1301 +Curve -225 -1296 -238 -1282 +Curve -241 -1275 -243 -1267 +Curve -240 -1260 -237 -1252 +Curve -236 -1250 -234 -1247 +Curve -221 -1231 -199 -1221 +<-------EndPath +Path 4 4 0 -235 347 +Curve -223 497 -362 620 +<-------EndPath +Path 4 3 0 -910 1657 +Curve -910 1658 -910 1658 +Curve -854 1703 -771 1727 +Curve -647 1763 -524 1807 +Curve -516 1810 -507 1813 +<-------EndPath +Path 4 4 0 -157 980 +Curve -158 1036 -175 1089 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 1168 -1832 +Curve 1045 -1836 922 -1840 +Curve 799 -1822 704 -1745 +Curve 686 -1729 667 -1712 +Curve 601 -1647 573 -1570 +Curve 520 -1693 576 -1800 +Curve 582 -1811 588 -1822 +Curve 638 -1917 708 -1999 +Curve 782 -2085 884 -2132 +Curve 908 -2141 932 -2150 +Curve 975 -2158 1018 -2166 +<-------EndPath +Path 1 0 -1 939 -1503 +Curve 946 -1500 953 -1496 +Curve 956 -1495 959 -1493 +Curve 1071 -1462 1165 -1396 +Curve 1194 -1375 1222 -1354 +<-------EndPath +Path 1 1 0 1222 -1354 +Curve 1196 -1437 1121 -1463 +<-------EndPath +Path 1 -1 0 1121 -1463 +Curve 1090 -1471 1059 -1479 +Curve 999 -1491 939 -1503 +<-------EndPath +Path 0 -1 0 939 -1503 +Curve 851 -1520 762 -1537 +<-------EndPath +Path 0 0 0 762 -1537 +Curve 801 -1497 812 -1440 +<-------EndPath +Path 1 -1 0 866 -815 +Curve 925 -824 984 -832 +Curve 988 -833 992 -834 +Curve 1008 -837 1024 -839 +Curve 1049 -843 1074 -847 +Curve 1454 -974 1491 -1064 +Curve 1528 -1154 1506 -1205 +Curve 1484 -1256 1373 -1337 +Curve 1262 -1419 1121 -1463 +<-------EndPath +Path 1 0 -1 1222 -1354 +Curve 1328 -1335 1414 -1218 +Curve 1500 -1101 1358 -1013 +Curve 1215 -925 1068 -889 +Curve 930 -855 866 -815 +<-------EndPath +Path -1 0 0 866 -815 +Curve 835 -813 804 -811 +Curve 724 -814 643 -817 +<-------EndPath +Path -1 -1 0 643 -817 +Curve 611 -816 579 -814 +Curve 562 -814 542 -796 +Curve 522 -775 502 -754 +Curve 488 -738 484 -721 +Curve 482 -708 480 -695 +<-------EndPath +Path -1 1 0 480 -695 +Curve 478 -677 484 -662 +Curve 500 -638 515 -613 +<-------EndPath +Path -1 3 0 515 -613 +Curve 524 -599 533 -584 +Curve 540 -575 546 -565 +Curve 555 -547 564 -528 +<-------EndPath +Path -1 -1 0 564 -528 +Curve 566 -537 567 -545 +<-------EndPath +Path 0 0 0 959 -1493 +Curve 1002 -1469 1023 -1421 +<-------EndPath +Path -1 -1 0 1043 -1959 +Curve 919 -2000 808 -1938 +Curve 708 -1882 630 -1797 +Curve 621 -1785 612 -1773 +Curve 546 -1685 573 -1570 +<-------EndPath +Path -1 0 0 230 -675 +Curve 253 -687 276 -699 +Curve 316 -727 334 -768 +Curve 338 -785 342 -801 +Curve 345 -821 334 -843 +Curve 323 -866 304 -882 +Curve 189 -914 -11 -1012 +Curve -295 -1151 -279 -1257 +Curve -276 -1279 -272 -1301 +Curve -269 -1311 -266 -1321 +Curve -246 -1376 -194 -1411 +Curve -114 -1465 -38 -1486 +Curve 27 -1503 92 -1520 +Curve 122 -1526 152 -1531 +Curve 155 -1532 157 -1532 +Curve 274 -1546 390 -1559 +Curve 414 -1560 437 -1561 +Curve 465 -1562 492 -1563 +Curve 520 -1563 548 -1562 +Curve 560 -1562 572 -1561 +Curve 625 -1557 678 -1553 +Curve 720 -1545 762 -1537 +<-------EndPath +Path 0 0 0 157 -1532 +Curve 185 -1511 191 -1479 +Curve 194 -1458 189 -1433 +<-------EndPath +Path 0 0 0 390 -1559 +Curve 405 -1544 420 -1529 +Curve 434 -1508 438 -1479 +<-------EndPath +Path -1 1 -1 462 -704 +Curve 471 -700 480 -695 +<-------EndPath +Path -1 0 -1 643 -817 +Curve 619 -819 594 -821 +Curve 511 -799 473 -727 +Curve 468 -716 462 -704 +<-------EndPath +Path 1 0 -1 462 -704 +Curve 461 -701 460 -697 +Curve 430 -616 466 -529 +Curve 481 -494 495 -458 +<-------EndPath +Path 1 3 0 495 -458 +Curve 504 -513 512 -568 +Curve 513 -577 514 -585 +Curve 515 -599 515 -613 +<-------EndPath +Path 3 -1 0 230 -675 +Curve 191 -662 152 -648 +Curve 150 -648 148 -647 +<-------EndPath +Path 3 0 -1 148 -647 +Curve 151 -641 153 -635 +<-------EndPath +Path 3 0 0 153 -635 +Curve 170 -515 140 -402 +Curve 108 -286 62 -177 +Curve 58 -168 53 -158 +Curve 5 -53 -75 28 +Curve -174 128 -299 69 +Curve -335 52 -335 39 +<-------EndPath +Path 3 0 -1 -335 39 +Curve -340 37 -344 35 +<-------EndPath +Path 3 -1 0 -344 35 +Curve -347 43 -349 51 +Curve -396 187 -443 323 +Curve -468 396 -487 486 +Curve -489 494 -490 501 +Curve -493 508 -495 515 +Curve -496 519 -496 522 +Curve -497 523 -497 524 +Curve -498 525 -498 526 +Curve -498 527 -498 528 +Curve -499 530 -499 531 +Curve -499 532 -499 533 +Curve -515 593 -520 656 +<-------EndPath +Path 3 -1 -1 -520 656 +Curve -519 656 -518 656 +<-------EndPath +Path 3 3 1 -518 656 +Curve -514 640 -509 624 +<-------EndPath +Path 3 0 0 495 -458 +Curve 492 -447 489 -435 +Curve 475 -381 461 -326 +Curve 444 -254 426 -181 +Curve 416 -137 393 -129 +Curve 354 -118 314 -107 +Curve 225 -85 134 -80 +Curve 142 -96 149 -112 +Curve 177 -164 204 -216 +Curve 265 -323 274 -447 +Curve 282 -577 230 -675 +<-------EndPath +Path 0 1 -1 556 -209 +Curve 555 -258 542 -308 +Curve 536 -329 530 -350 +<-------EndPath +Path 0 3 0 530 -350 +Curve 526 -331 521 -311 +Curve 492 -187 479 -61 +Curve 472 4 492 10 +<-------EndPath +Path 0 -1 0 492 10 +Curve 531 -89 556 -209 +<-------EndPath +Path 1 -1 0 556 -209 +Curve 563 -245 569 -280 +Curve 595 -443 564 -528 +<-------EndPath +Path 1 3 0 564 -528 +Curve 557 -488 550 -448 +Curve 550 -447 550 -446 +Curve 548 -435 546 -423 +Curve 538 -387 530 -350 +<-------EndPath +Path -1 -1 0 984 -832 +Curve 1004 -836 1024 -839 +<-------EndPath +Path -1 3 0 492 10 +Curve 479 41 466 71 +Curve 400 211 328 429 +<-------EndPath +Path -1 -1 0 328 429 +Curve 323 450 318 470 +<-------EndPath +Path -1 3 0 318 470 +Curve 317 495 319 507 +Curve 313 529 307 550 +<-------EndPath +Path -1 3 1 307 550 +Curve 294 581 295 656 +Curve 297 676 298 695 +Curve 311 801 323 907 +Curve 334 1017 357 1126 +Curve 377 1227 412 1323 +Curve 442 1404 462 1484 +Curve 466 1520 469 1555 +Curve 457 1576 445 1597 +Curve 396 1662 325 1692 +<-------EndPath +Path -1 2 1 325 1692 +Curve 341 1694 356 1696 +Curve 455 1679 559 1644 +Curve 587 1644 614 1643 +Curve 727 1682 623 1798 +Curve 550 1879 455 1901 +Curve 359 1922 272 1950 +Curve 184 1977 96 1981 +Curve 7 1985 -10 1906 +Curve -22 1836 -34 1766 +<-------EndPath +Path -1 3 1 -34 1766 +Curve -99 1774 -163 1782 +Curve -150 1702 -129 1625 +Curve -123 1599 -116 1573 +Curve -183 1627 -258 1670 +Curve -342 1716 -433 1739 +Curve -445 1731 -456 1722 +<-------EndPath +Path -1 2 1 -456 1722 +Curve -457 1800 -410 1864 +Curve -339 1864 -269 1892 +Curve -227 1908 -246 1953 +Curve -292 2057 -421 2038 +Curve -532 2022 -617 1948 +Curve -696 1879 -747 1783 +Curve -799 1687 -838 1595 +Curve -886 1480 -780 1421 +<-------EndPath +Path -1 3 1 -780 1421 +Curve -801 1386 -813 1348 +Curve -695 1316 -620 1257 +Curve -532 1187 -526 1073 +Curve -521 963 -534 856 +Curve -546 756 -518 656 +<-------EndPath +Path 3 -1 0 318 470 +Curve 318 466 318 461 +Curve 318 461 318 460 +Curve 323 445 328 429 +<-------EndPath +Path 3 3 1 -116 1573 +Curve -96 1555 -75 1537 +Curve 4 1465 75 1382 +Curve 146 1300 180 1195 +Curve 213 1092 226 985 +Curve 240 874 211 767 +Curve 194 712 176 656 +Curve 163 632 149 607 +Curve 143 593 136 578 +Curve 119 538 94 512 +<-------EndPath +Path 3 2 1 -34 1766 +Curve 7 1760 47 1753 +Curve 158 1731 269 1709 +Curve 297 1701 325 1692 +<-------EndPath +Path 0 0 0 -184 -1327 +Curve -225 -1322 -238 -1308 +Curve -241 -1301 -243 -1293 +Curve -240 -1286 -237 -1278 +Curve -236 -1276 -234 -1273 +Curve -221 -1257 -199 -1247 +<-------EndPath +Path 0 -1 0 148 -647 +Curve 50 -604 -66 -494 +Curve -184 -383 -275 -148 +Curve -310 -57 -344 35 +<-------EndPath +Path 0 0 0 -335 39 +Curve -333 35 -331 30 +<-------EndPath +Path 3 3 0 -193 309 +Curve -181 459 -320 582 +<-------EndPath +Path 3 2 1 -780 1421 +Curve -749 1473 -698 1518 +Curve -618 1587 -537 1656 +Curve -498 1689 -459 1721 +Curve -458 1722 -456 1722 +<-------EndPath +Path 2 2 1 -410 1864 +Curve -438 1866 -466 1868 +Curve -497 1870 -527 1871 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 1168 -1867 +Curve 1045 -1871 922 -1875 +Curve 799 -1857 704 -1780 +Curve 686 -1764 667 -1747 +Curve 601 -1683 573 -1606 +Curve 520 -1729 576 -1836 +Curve 582 -1847 588 -1858 +Curve 638 -1952 708 -2034 +Curve 782 -2120 884 -2167 +Curve 908 -2176 932 -2185 +Curve 975 -2193 1018 -2201 +<-------EndPath +Path -1 1 0 939 -1538 +Curve 999 -1526 1059 -1514 +Curve 1090 -1506 1121 -1498 +Curve 1262 -1454 1373 -1373 +Curve 1484 -1291 1506 -1240 +Curve 1528 -1190 1491 -1099 +Curve 1454 -1009 1074 -882 +Curve 1054 -879 1034 -876 +<-------EndPath +Path -1 -1 0 1034 -876 +Curve 1009 -872 984 -868 +<-------EndPath +Path -1 1 0 984 -868 +Curve 925 -859 866 -850 +<-------EndPath +Path -1 0 0 866 -850 +Curve 835 -849 804 -847 +Curve 724 -850 643 -852 +<-------EndPath +Path -1 -1 0 643 -852 +Curve 611 -851 579 -849 +Curve 562 -849 542 -832 +Curve 522 -811 502 -790 +Curve 488 -773 484 -756 +Curve 482 -743 480 -730 +<-------EndPath +Path -1 1 0 480 -730 +Curve 478 -712 484 -698 +Curve 500 -673 515 -648 +<-------EndPath +Path -1 4 0 515 -648 +Curve 524 -634 533 -620 +Curve 540 -610 546 -600 +Curve 555 -582 564 -564 +<-------EndPath +Path -1 -1 0 564 -564 +Curve 566 -573 567 -581 +<-------EndPath +Path 0 1 -1 959 -1528 +Curve 956 -1530 953 -1532 +Curve 946 -1535 939 -1538 +<-------EndPath +Path 0 -1 0 939 -1538 +Curve 851 -1555 762 -1572 +<-------EndPath +Path 0 0 0 762 -1572 +Curve 801 -1532 812 -1475 +<-------EndPath +Path 1 0 -1 1222 -1389 +Curve 1328 -1370 1414 -1253 +Curve 1500 -1137 1358 -1048 +Curve 1215 -960 1068 -924 +Curve 930 -890 866 -850 +<-------EndPath +Path 0 1 -1 1222 -1389 +Curve 1194 -1410 1165 -1431 +Curve 1071 -1497 959 -1528 +<-------EndPath +Path 0 0 0 959 -1528 +Curve 1002 -1504 1023 -1456 +<-------EndPath +Path 1 1 0 1121 -1498 +Curve 1196 -1472 1222 -1389 +<-------EndPath +Path -1 -1 0 1043 -1994 +Curve 919 -2035 808 -1973 +Curve 708 -1917 630 -1832 +Curve 621 -1820 612 -1808 +Curve 546 -1720 573 -1606 +<-------EndPath +Path 0 0 0 390 -1595 +Curve 405 -1580 420 -1565 +Curve 434 -1543 438 -1514 +<-------EndPath +Path -1 0 0 230 -710 +Curve 258 -722 276 -735 +Curve 316 -762 334 -804 +Curve 338 -820 342 -836 +Curve 345 -857 334 -879 +Curve 323 -901 304 -917 +Curve 189 -949 -11 -1047 +Curve -295 -1186 -279 -1292 +Curve -276 -1315 -272 -1337 +Curve -269 -1347 -266 -1356 +Curve -246 -1412 -194 -1447 +Curve -114 -1501 -38 -1522 +Curve 27 -1539 92 -1555 +Curve 122 -1561 152 -1567 +Curve 155 -1567 157 -1567 +Curve 274 -1581 390 -1595 +Curve 414 -1596 437 -1596 +Curve 465 -1598 492 -1599 +Curve 520 -1598 548 -1597 +Curve 560 -1597 572 -1596 +Curve 625 -1592 678 -1588 +Curve 720 -1580 762 -1572 +<-------EndPath +Path 0 0 0 157 -1567 +Curve 185 -1546 191 -1514 +Curve 194 -1494 189 -1469 +<-------EndPath +Path -1 0 -1 643 -852 +Curve 619 -854 594 -856 +Curve 511 -834 473 -762 +Curve 468 -751 462 -739 +<-------EndPath +Path -1 1 -1 462 -739 +Curve 471 -735 480 -730 +<-------EndPath +Path 4 1 0 515 -648 +Curve 515 -635 514 -621 +Curve 513 -612 512 -603 +Curve 504 -548 495 -493 +<-------EndPath +Path 4 0 0 495 -493 +Curve 492 -482 489 -470 +Curve 475 -416 461 -361 +Curve 444 -289 426 -216 +Curve 416 -172 393 -164 +Curve 354 -153 314 -142 +Curve 225 -121 134 -115 +Curve 142 -131 149 -147 +Curve 177 -200 204 -252 +Curve 265 -359 274 -482 +Curve 282 -612 230 -710 +<-------EndPath +Path 4 -1 0 230 -710 +Curve 191 -697 152 -684 +Curve 150 -683 148 -682 +<-------EndPath +Path 4 0 -1 148 -682 +Curve 151 -677 153 -671 +<-------EndPath +Path 4 0 0 153 -671 +Curve 170 -551 140 -437 +Curve 108 -321 62 -212 +Curve 58 -203 53 -193 +Curve 5 -88 -75 -7 +Curve -174 92 -299 33 +Curve -335 16 -335 3 +<-------EndPath +Path 4 0 -1 -335 3 +Curve -340 2 -344 0 +<-------EndPath +Path 4 -1 0 -344 0 +Curve -347 8 -349 15 +Curve -396 152 -443 288 +Curve -468 361 -487 450 +Curve -489 458 -490 466 +Curve -493 473 -495 480 +Curve -496 483 -496 486 +Curve -497 488 -497 489 +Curve -498 490 -498 491 +Curve -498 492 -498 493 +Curve -499 494 -499 495 +Curve -499 497 -499 498 +Curve -514 553 -520 611 +<-------EndPath +Path 4 2 1 -520 611 +Curve -519 638 -518 665 +<-------EndPath +Path 4 -1 1 -518 665 +Curve -516 715 -499 765 +Curve -459 881 -377 976 +Curve -369 987 -360 997 +<-------EndPath +Path 4 4 1 -360 997 +Curve -268 1112 -326 1159 +<-------EndPath +Path 1 0 -1 462 -739 +Curve 461 -736 460 -732 +Curve 430 -652 466 -565 +Curve 481 -529 495 -493 +<-------EndPath +Path 1 0 -1 530 -385 +Curve 536 -364 542 -343 +Curve 555 -294 556 -244 +<-------EndPath +Path 1 -1 0 556 -244 +Curve 563 -280 569 -316 +Curve 595 -478 564 -564 +<-------EndPath +Path 1 4 0 564 -564 +Curve 557 -524 550 -483 +Curve 550 -483 550 -482 +Curve 548 -471 546 -459 +Curve 538 -422 530 -385 +<-------EndPath +Path 0 4 0 530 -385 +Curve 526 -366 521 -346 +Curve 492 -222 479 -96 +Curve 472 -31 492 -25 +<-------EndPath +Path 0 -1 0 492 -25 +Curve 531 -125 556 -244 +<-------EndPath +Path -1 1 0 1034 -876 +Curve 1013 -873 992 -870 +Curve 988 -869 984 -868 +<-------EndPath +Path -1 4 0 328 394 +Curve 323 410 318 425 +Curve 318 426 318 426 +Curve 318 431 318 435 +<-------EndPath +Path -1 -1 0 318 435 +Curve 323 415 328 394 +<-------EndPath +Path 4 -1 0 328 394 +Curve 400 176 466 36 +Curve 479 6 492 -25 +<-------EndPath +Path -1 4 0 318 435 +Curve 316 453 313 471 +Curve 305 498 296 525 +<-------EndPath +Path -1 4 1 296 525 +Curve 282 567 281 615 +Curve 281 640 280 665 +Curve 258 777 256 893 +<-------EndPath +Path -1 -1 1 256 893 +Curve 256 899 256 904 +Curve 257 959 257 1013 +Curve 258 1073 262 1133 +Curve 263 1143 263 1153 +<-------EndPath +Path -1 4 1 263 1153 +Curve 271 1274 311 1389 +Curve 354 1509 356 1629 +Curve 239 1668 138 1688 +<-------EndPath +Path -1 3 1 138 1688 +Curve 151 1714 204 1726 +Curve 325 1754 450 1769 +Curve 562 1782 507 1876 +Curve 440 1988 304 1992 +Curve 184 1994 63 1996 +Curve -60 1997 -176 1972 +Curve -314 1942 -267 1844 +Curve -336 1836 -401 1799 +Curve -511 1735 -601 1650 +Curve -691 1566 -776 1439 +Curve -733 1343 -643 1269 +<-------EndPath +Path -1 4 1 -643 1269 +Curve -706 1186 -587 1125 +Curve -472 1067 -360 997 +<-------EndPath +Path -1 4 -1 256 893 +Curve 253 893 249 892 +<-------EndPath +Path -1 4 1 249 892 +Curve 250 898 250 904 +Curve 252 959 254 1013 +Curve 252 1074 250 1134 +Curve 250 1143 249 1151 +<-------EndPath +Path -1 4 -1 249 1151 +Curve 256 1152 263 1153 +<-------EndPath +Path 4 4 1 249 892 +Curve 241 779 223 665 +Curve 223 660 222 655 +Curve 202 528 189 402 +<-------EndPath +Path 4 4 1 249 1151 +Curve 235 1266 154 1353 +Curve 106 1406 37 1430 +Curve -72 1468 -164 1554 +Curve -168 1558 -172 1561 +Curve -185 1566 -210 1553 +Curve -263 1525 -315 1496 +<-------EndPath +Path 4 3 1 -315 1496 +Curve -386 1510 -336 1588 +Curve -273 1686 -141 1704 +Curve -111 1707 -93 1723 +Curve -5 1710 83 1697 +Curve 111 1693 138 1688 +<-------EndPath +Path 0 0 0 -184 -1362 +Curve -225 -1357 -238 -1344 +Curve -241 -1336 -243 -1328 +Curve -240 -1321 -237 -1314 +Curve -236 -1312 -234 -1309 +Curve -221 -1292 -199 -1282 +<-------EndPath +Path 0 -1 0 148 -682 +Curve 50 -639 -66 -529 +Curve -184 -418 -275 -183 +Curve -310 -92 -344 0 +<-------EndPath +Path 2 -1 -1 -520 611 +Curve -521 617 -521 623 +Curve -522 633 -522 643 +Curve -523 654 -523 665 +Curve -521 665 -518 665 +<-------EndPath +Path 4 4 0 -163 298 +Curve -151 448 -290 571 +<-------EndPath +Path 3 4 1 -315 1496 +Curve -368 1467 -420 1438 +Curve -525 1380 -613 1300 +Curve -628 1285 -643 1269 +<-------EndPath +Path 3 3 1 -93 1723 +Curve -86 1732 -78 1740 +Curve -35 1810 -160 1838 +Curve -214 1841 -267 1844 +<-------EndPath +Path 0 0 0 -335 3 +Curve -333 -1 -331 -5 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 1168 -1806 +Curve 1045 -1810 922 -1814 +Curve 799 -1796 704 -1719 +Curve 686 -1703 667 -1686 +Curve 601 -1622 573 -1545 +Curve 520 -1667 576 -1774 +Curve 582 -1785 588 -1796 +Curve 638 -1891 708 -1973 +Curve 782 -2059 884 -2106 +Curve 908 -2115 932 -2124 +Curve 975 -2132 1018 -2140 +<-------EndPath +Path 1 -1 0 1121 -1437 +Curve 1090 -1445 1059 -1453 +Curve 999 -1465 939 -1477 +<-------EndPath +Path 1 0 -1 939 -1477 +Curve 946 -1474 953 -1470 +Curve 956 -1469 959 -1467 +Curve 1071 -1436 1165 -1370 +Curve 1194 -1349 1222 -1328 +<-------EndPath +Path 1 1 0 1222 -1328 +Curve 1196 -1411 1121 -1437 +<-------EndPath +Path -1 1 0 1121 -1437 +Curve 1262 -1393 1373 -1311 +Curve 1484 -1230 1506 -1179 +Curve 1528 -1128 1491 -1038 +Curve 1454 -948 1074 -821 +Curve 1049 -817 1024 -813 +<-------EndPath +Path -1 -1 0 1024 -813 +Curve 1004 -810 984 -806 +<-------EndPath +Path -1 1 0 984 -806 +Curve 925 -798 866 -789 +<-------EndPath +Path -1 0 0 866 -789 +Curve 835 -787 804 -785 +Curve 724 -788 643 -791 +<-------EndPath +Path -1 -1 0 643 -791 +Curve 611 -790 579 -788 +Curve 562 -788 542 -770 +Curve 522 -749 502 -728 +Curve 488 -712 484 -695 +Curve 482 -682 480 -669 +<-------EndPath +Path -1 1 0 480 -669 +Curve 478 -651 484 -636 +Curve 500 -612 515 -587 +<-------EndPath +Path -1 3 0 515 -587 +Curve 524 -573 533 -558 +Curve 540 -549 546 -539 +Curve 555 -521 564 -502 +<-------EndPath +Path -1 -1 0 564 -502 +Curve 566 -511 567 -519 +<-------EndPath +Path 0 0 0 959 -1467 +Curve 1002 -1443 1023 -1395 +<-------EndPath +Path 1 0 -1 1222 -1328 +Curve 1328 -1309 1414 -1192 +Curve 1500 -1075 1358 -987 +Curve 1215 -899 1068 -863 +Curve 930 -829 866 -789 +<-------EndPath +Path -1 -1 0 1043 -1933 +Curve 919 -1974 808 -1912 +Curve 708 -1856 630 -1771 +Curve 621 -1759 612 -1747 +Curve 546 -1659 573 -1545 +<-------EndPath +Path -1 0 0 230 -649 +Curve 253 -661 276 -673 +Curve 316 -701 334 -742 +Curve 338 -759 342 -775 +Curve 345 -796 334 -818 +Curve 323 -840 304 -856 +Curve 189 -888 -11 -986 +Curve -295 -1125 -279 -1231 +Curve -276 -1253 -272 -1275 +Curve -269 -1285 -266 -1295 +Curve -246 -1350 -194 -1385 +Curve -114 -1439 -38 -1461 +Curve 27 -1478 92 -1494 +Curve 122 -1500 152 -1505 +Curve 155 -1506 157 -1506 +Curve 274 -1520 390 -1533 +Curve 414 -1534 437 -1535 +Curve 465 -1536 492 -1537 +Curve 520 -1537 548 -1536 +Curve 560 -1536 572 -1535 +Curve 625 -1531 678 -1527 +Curve 720 -1519 762 -1511 +Curve 851 -1494 939 -1477 +<-------EndPath +Path 0 0 0 157 -1506 +Curve 185 -1485 191 -1453 +Curve 194 -1432 189 -1407 +<-------EndPath +Path 0 0 0 390 -1533 +Curve 405 -1518 420 -1503 +Curve 434 -1482 438 -1453 +<-------EndPath +Path -1 1 -1 462 -678 +Curve 471 -674 480 -669 +<-------EndPath +Path -1 0 -1 643 -791 +Curve 619 -793 594 -795 +Curve 511 -773 473 -701 +Curve 468 -690 462 -678 +<-------EndPath +Path 1 0 -1 462 -678 +Curve 461 -675 460 -671 +Curve 430 -590 466 -503 +Curve 481 -468 495 -432 +<-------EndPath +Path 1 3 0 495 -432 +Curve 504 -487 512 -542 +Curve 513 -551 514 -559 +Curve 515 -573 515 -587 +<-------EndPath +Path 3 -1 0 230 -649 +Curve 191 -636 152 -622 +Curve 150 -622 148 -621 +<-------EndPath +Path 3 0 -1 148 -621 +Curve 151 -615 153 -609 +<-------EndPath +Path 3 0 0 153 -609 +Curve 170 -489 140 -376 +Curve 108 -260 62 -151 +Curve 58 -142 53 -132 +Curve 5 -27 -75 54 +Curve -174 154 -299 95 +Curve -335 78 -335 65 +<-------EndPath +Path 3 0 -1 -335 65 +Curve -340 63 -344 61 +<-------EndPath +Path 3 -1 0 -344 61 +Curve -347 69 -349 76 +Curve -396 213 -443 349 +Curve -468 422 -487 512 +Curve -489 520 -490 527 +Curve -493 534 -495 541 +Curve -496 544 -496 547 +Curve -497 549 -497 550 +Curve -498 551 -498 552 +Curve -498 553 -498 554 +Curve -499 555 -499 556 +Curve -499 558 -499 559 +Curve -515 620 -521 684 +Curve -522 695 -522 705 +Curve -563 817 -603 929 +Curve -614 961 -624 992 +Curve -676 1145 -749 1288 +Curve -799 1385 -859 1476 +<-------EndPath +Path 3 -1 1 -859 1476 +Curve -820 1509 -781 1542 +<-------EndPath +Path 3 2 1 -781 1542 +Curve -731 1578 -667 1610 +Curve -555 1664 -442 1717 +<-------EndPath +Path 3 -1 1 -442 1717 +Curve -392 1741 -341 1765 +Curve -316 1777 -290 1788 +<-------EndPath +Path 3 -1 0 -290 1788 +Curve -198 1657 -121 1505 +Curve -108 1477 -94 1448 +<-------EndPath +Path 3 3 1 -94 1448 +Curve -148 1355 -201 1261 +Curve -321 1050 -388 829 +Curve -457 597 -436 362 +<-------EndPath +Path 3 0 0 495 -432 +Curve 492 -421 489 -409 +Curve 475 -355 461 -300 +Curve 444 -228 426 -155 +Curve 416 -111 393 -103 +Curve 354 -92 314 -81 +Curve 225 -59 134 -54 +Curve 142 -70 149 -86 +Curve 177 -138 204 -190 +Curve 265 -297 274 -421 +Curve 282 -551 230 -649 +<-------EndPath +Path 3 1 0 530 -324 +Curve 538 -361 546 -397 +Curve 548 -409 550 -420 +Curve 550 -421 550 -422 +Curve 557 -462 564 -502 +<-------EndPath +Path -1 1 0 564 -502 +Curve 595 -417 569 -254 +Curve 563 -219 556 -183 +<-------EndPath +Path -1 0 0 556 -183 +Curve 531 -63 492 36 +<-------EndPath +Path -1 3 0 492 36 +Curve 479 67 466 97 +Curve 400 237 328 455 +<-------EndPath +Path -1 -1 0 328 455 +Curve 323 476 318 496 +<-------EndPath +Path -1 3 0 318 496 +Curve 319 521 319 546 +Curve 321 567 323 588 +Curve 329 647 346 707 +<-------EndPath +Path -1 3 1 346 707 +Curve 414 859 486 1000 +Curve 487 1001 487 1002 +Curve 589 1203 693 1371 +Curve 826 1586 665 1685 +Curve 661 1688 656 1690 +<-------EndPath +Path -1 2 -1 656 1690 +Curve 662 1690 668 1690 +<-------EndPath +Path -1 2 1 668 1690 +Curve 682 1692 695 1694 +Curve 750 1688 800 1663 +Curve 850 1637 905 1620 +Curve 961 1602 1010 1629 +Curve 1066 1660 1040 1719 +Curve 1016 1770 979 1814 +Curve 944 1855 895 1876 +Curve 844 1896 793 1916 +Curve 744 1930 695 1944 +Curve 641 1957 587 1970 +Curve 531 1980 474 1989 +Curve 420 1990 386 1949 +Curve 353 1907 341 1857 +<-------EndPath +Path -1 2 -1 341 1857 +Curve 338 1850 335 1842 +<-------EndPath +Path -1 3 1 335 1842 +Curve 274 1866 212 1889 +Curve 128 1816 59 1710 +Curve 47 1690 35 1670 +Curve -15 1584 -65 1498 +<-------EndPath +Path -1 -1 1 -65 1498 +Curve -80 1473 -94 1448 +<-------EndPath +Path 3 -1 0 -94 1448 +Curve -92 1444 -90 1440 +Curve -76 1461 -65 1498 +<-------EndPath +Path 3 0 0 492 36 +Curve 472 30 479 -35 +Curve 492 -161 521 -285 +Curve 526 -305 530 -324 +<-------EndPath +Path 1 0 -1 530 -324 +Curve 536 -303 542 -282 +Curve 555 -232 556 -183 +<-------EndPath +Path 1 -1 0 984 -806 +Curve 988 -807 992 -808 +Curve 1008 -811 1024 -813 +<-------EndPath +Path 0 0 0 762 -1511 +Curve 801 -1471 812 -1414 +<-------EndPath +Path -1 3 0 328 455 +Curve 323 471 318 486 +Curve 318 487 318 487 +Curve 318 492 318 496 +<-------EndPath +Path 3 3 1 346 707 +Curve 328 666 310 625 +<-------EndPath +Path 3 3 0 210 1201 +Curve 172 1259 182 1330 +<-------EndPath +Path 2 3 1 656 1690 +Curve 612 1714 567 1737 +Curve 461 1791 335 1842 +<-------EndPath +Path 0 0 0 -184 -1301 +Curve -225 -1296 -238 -1282 +Curve -241 -1275 -243 -1267 +Curve -240 -1260 -237 -1252 +Curve -236 -1250 -234 -1247 +Curve -221 -1231 -199 -1221 +<-------EndPath +Path 0 -1 0 148 -621 +Curve 50 -578 -66 -468 +Curve -184 -357 -275 -122 +Curve -310 -31 -344 61 +<-------EndPath +Path 0 0 0 -335 65 +Curve -333 61 -331 56 +<-------EndPath +Path 3 3 0 -113 335 +Curve -102 485 -241 608 +<-------EndPath +Path 2 -1 1 -781 1542 +Curve -811 1584 -827 1637 +Curve -836 1668 -824 1701 +Curve -803 1750 -781 1798 +Curve -758 1844 -722 1882 +Curve -683 1915 -644 1947 +Curve -602 1976 -559 2004 +Curve -513 2034 -460 2045 +Curve -409 2052 -357 2059 +Curve -299 2062 -245 2040 +Curve -196 2019 -167 1973 +Curve -139 1926 -160 1907 +Curve -181 1888 -206 1891 +Curve -246 1888 -285 1884 +Curve -339 1873 -380 1840 +Curve -426 1803 -440 1748 +Curve -441 1733 -442 1717 +<-------EndPath +Path 3 3 0 -36 969 +Curve -37 1029 -57 1086 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 1168 -1832 +Curve 1045 -1836 922 -1840 +Curve 799 -1822 704 -1745 +Curve 686 -1729 667 -1712 +Curve 601 -1647 573 -1570 +Curve 520 -1693 576 -1800 +Curve 582 -1811 588 -1822 +Curve 638 -1917 708 -1999 +Curve 782 -2085 884 -2132 +Curve 908 -2141 932 -2150 +Curve 975 -2158 1018 -2166 +<-------EndPath +Path 1 0 -1 939 -1503 +Curve 946 -1500 953 -1496 +Curve 956 -1495 959 -1493 +Curve 1071 -1462 1165 -1396 +Curve 1194 -1375 1222 -1354 +<-------EndPath +Path 1 1 0 1222 -1354 +Curve 1196 -1437 1121 -1463 +<-------EndPath +Path 1 -1 0 1121 -1463 +Curve 1090 -1471 1059 -1479 +Curve 999 -1491 939 -1503 +<-------EndPath +Path 0 -1 0 939 -1503 +Curve 851 -1520 762 -1537 +<-------EndPath +Path 0 0 0 762 -1537 +Curve 801 -1497 812 -1440 +<-------EndPath +Path 1 -1 0 866 -815 +Curve 925 -824 984 -832 +Curve 988 -833 992 -834 +Curve 1008 -837 1024 -839 +Curve 1049 -843 1074 -847 +Curve 1454 -974 1491 -1064 +Curve 1528 -1154 1506 -1205 +Curve 1484 -1256 1373 -1337 +Curve 1262 -1419 1121 -1463 +<-------EndPath +Path 1 0 -1 1222 -1354 +Curve 1328 -1335 1414 -1218 +Curve 1500 -1101 1358 -1013 +Curve 1215 -925 1068 -889 +Curve 930 -855 866 -815 +<-------EndPath +Path -1 0 0 866 -815 +Curve 835 -813 804 -811 +Curve 724 -814 643 -817 +<-------EndPath +Path -1 -1 0 643 -817 +Curve 611 -816 579 -814 +Curve 562 -814 542 -796 +Curve 522 -775 502 -754 +Curve 488 -738 484 -721 +Curve 482 -708 480 -695 +<-------EndPath +Path -1 1 0 480 -695 +Curve 478 -677 484 -662 +Curve 500 -638 515 -613 +<-------EndPath +Path -1 4 0 515 -613 +Curve 524 -599 533 -584 +Curve 540 -575 546 -565 +Curve 555 -547 564 -528 +<-------EndPath +Path -1 -1 0 564 -528 +Curve 566 -537 567 -545 +<-------EndPath +Path 0 0 0 959 -1493 +Curve 1002 -1469 1023 -1421 +<-------EndPath +Path -1 -1 0 1043 -1959 +Curve 919 -2000 808 -1938 +Curve 708 -1882 630 -1797 +Curve 621 -1785 612 -1773 +Curve 546 -1685 573 -1570 +<-------EndPath +Path -1 0 0 230 -675 +Curve 253 -687 276 -699 +Curve 316 -727 334 -768 +Curve 338 -785 342 -801 +Curve 345 -821 334 -843 +Curve 323 -866 304 -882 +Curve 189 -914 -11 -1012 +Curve -295 -1151 -279 -1257 +Curve -276 -1279 -272 -1301 +Curve -269 -1311 -266 -1321 +Curve -246 -1376 -194 -1411 +Curve -114 -1465 -38 -1486 +Curve 27 -1503 92 -1520 +Curve 122 -1526 152 -1531 +Curve 155 -1532 157 -1532 +Curve 274 -1546 390 -1559 +Curve 414 -1560 437 -1561 +Curve 465 -1562 492 -1563 +Curve 520 -1563 548 -1562 +Curve 560 -1562 572 -1561 +Curve 625 -1557 678 -1553 +Curve 720 -1545 762 -1537 +<-------EndPath +Path 0 0 0 157 -1532 +Curve 185 -1511 191 -1479 +Curve 194 -1458 189 -1433 +<-------EndPath +Path 0 0 0 390 -1559 +Curve 405 -1544 420 -1529 +Curve 434 -1508 438 -1479 +<-------EndPath +Path -1 1 -1 462 -704 +Curve 471 -700 480 -695 +<-------EndPath +Path -1 0 -1 643 -817 +Curve 619 -819 594 -821 +Curve 511 -799 473 -727 +Curve 468 -716 462 -704 +<-------EndPath +Path 1 0 -1 462 -704 +Curve 461 -701 460 -697 +Curve 430 -616 466 -529 +Curve 481 -494 495 -458 +<-------EndPath +Path 1 4 0 495 -458 +Curve 504 -513 512 -568 +Curve 513 -577 514 -585 +Curve 515 -599 515 -613 +<-------EndPath +Path 4 -1 0 230 -675 +Curve 191 -662 152 -648 +Curve 150 -648 148 -647 +<-------EndPath +Path 4 0 -1 148 -647 +Curve 151 -641 153 -635 +<-------EndPath +Path 4 0 0 153 -635 +Curve 170 -515 140 -402 +Curve 108 -286 62 -177 +Curve 58 -168 53 -158 +Curve 5 -53 -75 28 +Curve -174 128 -299 69 +Curve -335 52 -335 39 +<-------EndPath +Path 4 0 -1 -335 39 +Curve -340 37 -344 35 +<-------EndPath +Path 4 -1 0 -344 35 +Curve -347 43 -349 51 +Curve -396 187 -443 323 +Curve -468 396 -487 486 +Curve -489 494 -490 501 +Curve -493 508 -495 515 +Curve -496 519 -496 522 +Curve -497 523 -497 524 +Curve -498 525 -498 526 +Curve -498 527 -498 528 +Curve -499 530 -499 531 +Curve -499 532 -499 533 +Curve -505 558 -511 583 +<-------EndPath +Path 4 2 1 -511 583 +Curve -513 604 -514 624 +Curve -514 631 -513 638 +<-------EndPath +Path 4 -1 1 -513 638 +Curve -512 679 -495 721 +Curve -490 733 -485 744 +Curve -473 765 -460 786 +<-------EndPath +Path 4 4 1 -460 786 +Curve -396 880 -358 987 +Curve -321 1084 -284 1180 +Curve -241 1281 -204 1385 +Curve -167 1488 -162 1599 +Curve -160 1644 -163 1687 +<-------EndPath +Path 4 -1 1 -163 1687 +Curve -169 1752 -188 1814 +Curve -196 1835 -196 1859 +Curve -127 1860 -57 1861 +<-------EndPath +Path 4 3 1 -57 1861 +Curve -14 1862 29 1863 +Curve 150 1866 265 1825 +Curve 313 1807 357 1783 +<-------EndPath +Path 4 -1 1 357 1783 +Curve 392 1761 427 1738 +Curve 430 1723 433 1707 +Curve 466 1470 412 1233 +Curve 397 1174 381 1115 +Curve 312 878 291 638 +<-------EndPath +Path 4 2 1 291 638 +Curve 294 627 296 615 +<-------EndPath +Path 4 -1 1 296 615 +Curve 297 608 297 600 +Curve 300 568 307 550 +<-------EndPath +Path 4 -1 0 307 550 +Curve 313 529 319 507 +Curve 317 495 318 470 +Curve 318 466 318 461 +Curve 318 461 318 460 +Curve 323 445 328 429 +Curve 400 211 466 71 +Curve 479 41 492 10 +<-------EndPath +Path 4 0 0 492 10 +Curve 472 4 479 -61 +Curve 492 -187 521 -311 +Curve 526 -331 530 -350 +<-------EndPath +Path 4 1 0 530 -350 +Curve 538 -387 546 -423 +Curve 548 -435 550 -446 +Curve 550 -447 550 -448 +Curve 557 -488 564 -528 +<-------EndPath +Path -1 1 0 564 -528 +Curve 595 -443 569 -280 +Curve 563 -245 556 -209 +<-------EndPath +Path -1 0 0 556 -209 +Curve 531 -89 492 10 +<-------EndPath +Path 4 0 0 495 -458 +Curve 492 -447 489 -435 +Curve 475 -381 461 -326 +Curve 444 -254 426 -181 +Curve 416 -137 393 -129 +Curve 354 -118 314 -107 +Curve 225 -85 134 -80 +Curve 142 -96 149 -112 +Curve 177 -164 204 -216 +Curve 265 -323 274 -447 +Curve 282 -577 230 -675 +<-------EndPath +Path 0 1 -1 556 -209 +Curve 555 -258 542 -308 +Curve 536 -329 530 -350 +<-------EndPath +Path -1 -1 0 984 -832 +Curve 1004 -836 1024 -839 +<-------EndPath +Path -1 -1 0 328 429 +Curve 323 450 318 470 +<-------EndPath +Path -1 2 1 296 615 +Curve 296 627 295 638 +<-------EndPath +Path -1 2 -1 295 638 +Curve 293 638 291 638 +<-------EndPath +Path -1 3 1 357 1783 +Curve 373 1802 388 1820 +Curve 504 1777 597 1767 +Curve 661 1760 674 1826 +Curve 696 1940 590 1996 +Curve 492 2047 385 2067 +Curve 372 2068 359 2069 +Curve 306 2090 247 2092 +Curve 138 2083 29 2074 +Curve -2 2066 -18 2048 +Curve -91 1973 -57 1861 +<-------EndPath +Path 3 3 1 388 1820 +Curve 399 1829 409 1837 +<-------EndPath +Path 0 0 0 -184 -1327 +Curve -225 -1322 -238 -1308 +Curve -241 -1301 -243 -1293 +Curve -240 -1286 -237 -1278 +Curve -236 -1276 -234 -1273 +Curve -221 -1257 -199 -1247 +<-------EndPath +Path 0 -1 0 148 -647 +Curve 50 -604 -66 -494 +Curve -184 -383 -275 -148 +Curve -310 -57 -344 35 +<-------EndPath +Path 0 0 0 -335 39 +Curve -333 35 -331 30 +<-------EndPath +Path 2 -1 -1 -518 638 +Curve -516 638 -513 638 +<-------EndPath +Path 2 -1 0 -511 583 +Curve -515 611 -518 638 +<-------EndPath +Path -1 4 -1 -471 788 +Curve -466 787 -460 786 +<-------EndPath +Path -1 -1 1 -471 788 +Curve -478 766 -485 744 +<-------EndPath +Path -1 4 1 -567 1458 +Curve -612 1412 -666 1388 +Curve -625 1359 -584 1330 +Curve -496 1258 -428 1184 +Curve -361 1109 -406 978 +Curve -439 883 -471 788 +<-------EndPath +Path 4 4 0 -193 309 +Curve -181 459 -320 582 +<-------EndPath +Path 3 4 1 -326 1706 +Curve -383 1653 -440 1600 +Curve -490 1558 -526 1507 +Curve -547 1483 -567 1458 +<-------EndPath +Path 3 -1 1 -567 1458 +Curve -625 1484 -639 1537 +Curve -659 1615 -637 1691 +Curve -607 1799 -569 1907 +Curve -549 1964 -515 2000 +Curve -504 2020 -479 2029 +Curve -446 2040 -413 2051 +Curve -321 2079 -210 2041 +Curve -166 2025 -150 1989 +Curve -138 1960 -159 1942 +Curve -230 1880 -328 1881 +Curve -363 1835 -362 1774 +Curve -360 1771 -357 1767 +Curve -342 1737 -326 1706 +<-------EndPath +Path 4 -1 1 -326 1706 +Curve -300 1733 -274 1759 +Curve -203 1726 -163 1687 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 1168 -1867 +Curve 1045 -1871 922 -1875 +Curve 799 -1857 704 -1780 +Curve 686 -1764 667 -1747 +Curve 601 -1683 573 -1606 +Curve 520 -1729 576 -1836 +Curve 582 -1847 588 -1858 +Curve 638 -1952 708 -2034 +Curve 782 -2120 884 -2167 +Curve 908 -2176 932 -2185 +Curve 975 -2193 1018 -2201 +<-------EndPath +Path -1 1 0 939 -1538 +Curve 999 -1526 1059 -1514 +Curve 1090 -1506 1121 -1498 +Curve 1262 -1454 1373 -1373 +Curve 1484 -1291 1506 -1240 +Curve 1528 -1190 1491 -1099 +Curve 1454 -1009 1074 -882 +Curve 1054 -879 1034 -876 +<-------EndPath +Path -1 -1 0 1034 -876 +Curve 1009 -872 984 -868 +<-------EndPath +Path -1 1 0 984 -868 +Curve 925 -859 866 -850 +<-------EndPath +Path -1 0 0 866 -850 +Curve 835 -849 804 -847 +Curve 724 -850 643 -852 +<-------EndPath +Path -1 -1 0 643 -852 +Curve 611 -851 579 -849 +Curve 562 -849 542 -832 +Curve 522 -811 502 -790 +Curve 488 -773 484 -756 +Curve 482 -743 480 -730 +<-------EndPath +Path -1 1 0 480 -730 +Curve 478 -712 484 -698 +Curve 500 -673 515 -648 +<-------EndPath +Path -1 4 0 515 -648 +Curve 524 -634 533 -620 +Curve 540 -610 546 -600 +Curve 555 -582 564 -564 +<-------EndPath +Path -1 -1 0 564 -564 +Curve 566 -573 567 -581 +<-------EndPath +Path 0 1 -1 959 -1528 +Curve 956 -1530 953 -1532 +Curve 946 -1535 939 -1538 +<-------EndPath +Path 0 -1 0 939 -1538 +Curve 851 -1555 762 -1572 +<-------EndPath +Path 0 0 0 762 -1572 +Curve 801 -1532 812 -1475 +<-------EndPath +Path 1 0 -1 1222 -1389 +Curve 1328 -1370 1414 -1253 +Curve 1500 -1137 1358 -1048 +Curve 1215 -960 1068 -924 +Curve 930 -890 866 -850 +<-------EndPath +Path 0 1 -1 1222 -1389 +Curve 1194 -1410 1165 -1431 +Curve 1071 -1497 959 -1528 +<-------EndPath +Path 0 0 0 959 -1528 +Curve 1002 -1504 1023 -1456 +<-------EndPath +Path 1 1 0 1121 -1498 +Curve 1196 -1472 1222 -1389 +<-------EndPath +Path -1 -1 0 1043 -1994 +Curve 919 -2035 808 -1973 +Curve 708 -1917 630 -1832 +Curve 621 -1820 612 -1808 +Curve 546 -1720 573 -1606 +<-------EndPath +Path -1 0 0 230 -710 +Curve 258 -722 276 -735 +Curve 316 -762 334 -804 +Curve 338 -820 342 -836 +Curve 345 -857 334 -879 +Curve 323 -901 304 -917 +Curve 189 -949 -11 -1047 +Curve -295 -1186 -279 -1292 +Curve -276 -1315 -272 -1337 +Curve -269 -1347 -266 -1356 +Curve -246 -1412 -194 -1447 +Curve -114 -1501 -38 -1522 +Curve 27 -1539 92 -1555 +Curve 122 -1561 152 -1567 +Curve 155 -1567 157 -1567 +Curve 274 -1581 390 -1595 +Curve 414 -1596 437 -1596 +Curve 465 -1598 492 -1599 +Curve 520 -1598 548 -1597 +Curve 560 -1597 572 -1596 +Curve 625 -1592 678 -1588 +Curve 720 -1580 762 -1572 +<-------EndPath +Path 0 0 0 390 -1595 +Curve 405 -1580 420 -1565 +Curve 434 -1543 438 -1514 +<-------EndPath +Path 0 0 0 157 -1567 +Curve 185 -1546 191 -1514 +Curve 194 -1494 189 -1469 +<-------EndPath +Path -1 0 -1 643 -852 +Curve 619 -854 594 -856 +Curve 511 -834 473 -762 +Curve 468 -751 462 -739 +<-------EndPath +Path -1 1 -1 462 -739 +Curve 471 -735 480 -730 +<-------EndPath +Path 4 1 0 515 -648 +Curve 515 -635 514 -621 +Curve 513 -612 512 -603 +Curve 504 -548 495 -493 +<-------EndPath +Path 4 0 0 495 -493 +Curve 492 -482 489 -470 +Curve 475 -416 461 -361 +Curve 444 -289 426 -216 +Curve 416 -172 393 -164 +Curve 354 -153 314 -142 +Curve 225 -121 134 -115 +Curve 142 -131 149 -147 +Curve 177 -200 204 -252 +Curve 265 -359 274 -482 +Curve 282 -612 230 -710 +<-------EndPath +Path 4 -1 0 230 -710 +Curve 191 -697 152 -684 +Curve 150 -683 148 -682 +<-------EndPath +Path 4 0 -1 148 -682 +Curve 151 -677 153 -671 +<-------EndPath +Path 4 0 0 153 -671 +Curve 170 -551 140 -437 +Curve 108 -321 62 -212 +Curve 58 -203 53 -193 +Curve 5 -88 -75 -7 +Curve -174 92 -299 33 +Curve -335 16 -335 3 +<-------EndPath +Path 4 0 -1 -335 3 +Curve -340 2 -344 0 +<-------EndPath +Path 4 -1 0 -344 0 +Curve -347 8 -349 15 +Curve -396 152 -443 288 +Curve -460 346 -476 404 +Curve -482 427 -487 450 +Curve -488 452 -488 454 +Curve -489 460 -490 466 +Curve -493 473 -495 480 +Curve -496 483 -496 486 +Curve -497 488 -497 489 +Curve -498 490 -498 491 +Curve -498 492 -498 493 +Curve -499 494 -499 495 +Curve -499 497 -499 498 +Curve -503 515 -507 531 +Curve -513 569 -519 607 +<-------EndPath +Path 4 -1 1 -519 607 +Curve -519 607 -518 607 +Curve -515 610 -512 613 +Curve -508 740 -459 841 +Curve -408 947 -388 1064 +Curve -385 1083 -381 1102 +<-------EndPath +Path 4 4 1 -381 1102 +Curve -368 1202 -377 1305 +Curve -385 1382 -392 1459 +<-------EndPath +Path 4 3 1 -392 1459 +Curve -397 1507 -402 1554 +Curve -405 1613 -407 1672 +<-------EndPath +Path 4 -1 1 -407 1672 +Curve -407 1673 -407 1674 +Curve -404 1727 -393 1772 +Curve -352 1785 -311 1797 +<-------EndPath +Path 4 3 1 -311 1797 +Curve -218 1821 -134 1826 +Curve -12 1830 136 1820 +<-------EndPath +Path 4 -1 1 136 1820 +Curve 138 1820 139 1819 +Curve 288 1808 261 1685 +Curve 236 1574 234 1464 +Curve 234 1463 234 1462 +<-------EndPath +Path 4 4 1 234 1462 +Curve 234 1452 234 1442 +Curve 234 1321 245 1198 +Curve 255 1077 273 958 +Curve 292 835 286 714 +Curve 284 670 281 626 +Curve 281 621 281 615 +Curve 283 571 294 531 +Curve 295 528 296 525 +<-------EndPath +Path 4 4 0 296 525 +Curve 303 502 310 479 +<-------EndPath +Path 4 2 1 310 479 +Curve 311 477 311 474 +Curve 313 471 315 467 +<-------EndPath +Path 4 -1 0 315 467 +Curve 316 461 317 454 +Curve 318 445 318 435 +Curve 318 431 318 426 +Curve 318 426 318 425 +Curve 322 415 325 404 +Curve 327 399 328 394 +Curve 400 176 466 36 +Curve 479 6 492 -25 +<-------EndPath +Path 4 0 0 492 -25 +Curve 472 -31 479 -96 +Curve 492 -222 521 -346 +Curve 526 -366 530 -385 +<-------EndPath +Path 4 1 0 530 -385 +Curve 538 -422 546 -459 +Curve 548 -471 550 -482 +Curve 550 -483 550 -483 +Curve 557 -524 564 -564 +<-------EndPath +Path -1 1 0 564 -564 +Curve 595 -478 569 -316 +Curve 563 -280 556 -244 +<-------EndPath +Path -1 0 0 556 -244 +Curve 531 -125 492 -25 +<-------EndPath +Path 1 0 -1 462 -739 +Curve 461 -736 460 -732 +Curve 430 -652 466 -565 +Curve 481 -529 495 -493 +<-------EndPath +Path 1 0 -1 530 -385 +Curve 536 -364 542 -343 +Curve 555 -294 556 -244 +<-------EndPath +Path -1 1 0 1034 -876 +Curve 1013 -873 992 -870 +Curve 988 -869 984 -868 +<-------EndPath +Path 4 4 1 218 626 +Curve 214 595 209 564 +Curve 207 548 204 531 +Curve 200 493 195 454 +Curve 192 429 189 404 +<-------EndPath +Path -1 -1 0 318 435 +Curve 322 420 326 404 +Curve 327 399 328 394 +<-------EndPath +Path 2 -1 0 310 479 +Curve 312 475 313 471 +Curve 314 469 315 467 +<-------EndPath +Path 4 -1 1 234 1462 +Curve 288 1443 360 1367 +Curve 447 1275 475 1151 +Curve 502 1030 471 912 +Curve 439 795 375 692 +Curve 310 590 310 479 +<-------EndPath +Path 3 -1 -1 137 1829 +Curve 137 1825 136 1820 +<-------EndPath +Path 3 -1 1 -311 1797 +Curve -386 1907 -308 2009 +Curve -291 2022 -273 2035 +Curve -163 2087 -39 2082 +Curve 87 2075 215 2079 +Curve 361 2085 410 1967 +Curve 440 1897 368 1899 +Curve 228 1901 137 1829 +<-------EndPath +Path 0 0 0 -184 -1362 +Curve -225 -1357 -238 -1344 +Curve -241 -1336 -243 -1328 +Curve -240 -1321 -237 -1314 +Curve -236 -1312 -234 -1309 +Curve -221 -1292 -199 -1282 +<-------EndPath +Path 0 -1 0 148 -682 +Curve 50 -639 -66 -529 +Curve -184 -418 -275 -183 +Curve -310 -92 -344 0 +<-------EndPath +Path 4 4 0 -163 298 +Curve -159 352 -174 404 +Curve -185 429 -195 454 +Curve -216 493 -250 531 +Curve -270 551 -290 571 +<-------EndPath +Path -1 -1 1 -519 607 +Curve -519 607 -518 607 +<-------EndPath +Path -1 -1 0 -519 607 +Curve -520 609 -520 611 +<-------EndPath +Path -1 2 1 -520 611 +Curve -520 619 -520 626 +<-------EndPath +Path -1 2 -1 -520 626 +Curve -521 626 -521 626 +Curve -521 625 -521 623 +Curve -521 623 -521 622 +Curve -521 617 -520 611 +<-------EndPath +Path 4 -1 1 -381 1102 +Curve -519 1126 -483 1262 +Curve -464 1316 -445 1369 +<-------EndPath +Path 4 3 1 -445 1369 +Curve -422 1419 -392 1459 +<-------EndPath +Path 3 -1 1 -445 1369 +Curve -594 1379 -558 1505 +Curve -543 1561 -502 1603 +Curve -458 1649 -407 1672 +<-------EndPath +Path 0 0 0 -335 3 +Curve -333 -1 -331 -5 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 1168 -1806 +Curve 1045 -1810 922 -1814 +Curve 799 -1796 704 -1719 +Curve 686 -1703 667 -1686 +Curve 601 -1622 573 -1545 +Curve 520 -1667 576 -1774 +Curve 582 -1785 588 -1796 +Curve 638 -1891 708 -1973 +Curve 782 -2059 884 -2106 +Curve 908 -2115 932 -2124 +Curve 975 -2132 1018 -2140 +<-------EndPath +Path 1 -1 0 1121 -1437 +Curve 1090 -1445 1059 -1453 +Curve 999 -1465 939 -1477 +<-------EndPath +Path 1 0 -1 939 -1477 +Curve 946 -1474 953 -1470 +Curve 956 -1469 959 -1467 +Curve 1071 -1436 1165 -1370 +Curve 1194 -1349 1222 -1328 +<-------EndPath +Path 1 1 0 1222 -1328 +Curve 1196 -1411 1121 -1437 +<-------EndPath +Path -1 1 0 1121 -1437 +Curve 1262 -1393 1373 -1311 +Curve 1484 -1230 1506 -1179 +Curve 1528 -1128 1491 -1038 +Curve 1454 -948 1074 -821 +Curve 1049 -817 1024 -813 +<-------EndPath +Path -1 -1 0 1024 -813 +Curve 1004 -810 984 -806 +<-------EndPath +Path -1 1 0 984 -806 +Curve 925 -798 866 -789 +<-------EndPath +Path -1 0 0 866 -789 +Curve 835 -787 804 -785 +Curve 724 -788 643 -791 +<-------EndPath +Path -1 -1 0 643 -791 +Curve 611 -790 579 -788 +Curve 562 -788 542 -770 +Curve 522 -749 502 -728 +Curve 488 -712 484 -695 +Curve 482 -682 480 -669 +<-------EndPath +Path -1 1 0 480 -669 +Curve 478 -651 484 -636 +Curve 500 -612 515 -587 +<-------EndPath +Path -1 3 0 515 -587 +Curve 524 -573 533 -558 +Curve 540 -549 546 -539 +Curve 555 -521 564 -502 +<-------EndPath +Path -1 -1 0 564 -502 +Curve 566 -511 567 -519 +<-------EndPath +Path 0 0 0 959 -1467 +Curve 1002 -1443 1023 -1395 +<-------EndPath +Path 1 0 -1 1222 -1328 +Curve 1328 -1309 1414 -1192 +Curve 1500 -1075 1358 -987 +Curve 1215 -899 1068 -863 +Curve 930 -829 866 -789 +<-------EndPath +Path -1 -1 0 1043 -1933 +Curve 919 -1974 808 -1912 +Curve 708 -1856 630 -1771 +Curve 621 -1759 612 -1747 +Curve 546 -1659 573 -1545 +<-------EndPath +Path -1 0 0 230 -649 +Curve 253 -661 276 -673 +Curve 316 -701 334 -742 +Curve 338 -759 342 -775 +Curve 345 -796 334 -818 +Curve 323 -840 304 -856 +Curve 189 -888 -11 -986 +Curve -295 -1125 -279 -1231 +Curve -276 -1253 -272 -1275 +Curve -269 -1285 -266 -1295 +Curve -246 -1350 -194 -1385 +Curve -114 -1439 -38 -1461 +Curve 27 -1478 92 -1494 +Curve 122 -1500 152 -1505 +Curve 155 -1506 157 -1506 +Curve 274 -1520 390 -1533 +Curve 414 -1534 437 -1535 +Curve 465 -1536 492 -1537 +Curve 520 -1537 548 -1536 +Curve 560 -1536 572 -1535 +Curve 625 -1531 678 -1527 +Curve 720 -1519 762 -1511 +Curve 851 -1494 939 -1477 +<-------EndPath +Path 0 0 0 157 -1506 +Curve 185 -1485 191 -1453 +Curve 194 -1432 189 -1407 +<-------EndPath +Path 0 0 0 390 -1533 +Curve 405 -1518 420 -1503 +Curve 434 -1482 438 -1453 +<-------EndPath +Path 0 1 -1 495 -432 +Curve 481 -468 466 -503 +Curve 430 -590 460 -671 +Curve 461 -675 462 -678 +<-------EndPath +Path 0 -1 -1 462 -678 +Curve 468 -690 473 -701 +Curve 511 -773 594 -795 +Curve 619 -793 643 -791 +<-------EndPath +Path -1 1 -1 462 -678 +Curve 471 -674 480 -669 +<-------EndPath +Path 3 1 0 515 -587 +Curve 515 -573 514 -559 +Curve 513 -551 512 -542 +Curve 504 -487 495 -432 +<-------EndPath +Path 3 0 0 495 -432 +Curve 492 -421 489 -409 +Curve 475 -355 461 -300 +Curve 444 -228 426 -155 +Curve 416 -111 393 -103 +Curve 354 -92 314 -81 +Curve 225 -59 134 -54 +Curve 142 -70 149 -86 +Curve 177 -138 204 -190 +Curve 265 -297 274 -421 +Curve 282 -551 230 -649 +<-------EndPath +Path 3 -1 0 230 -649 +Curve 191 -636 152 -622 +Curve 150 -622 148 -621 +<-------EndPath +Path 3 0 -1 148 -621 +Curve 151 -615 153 -609 +<-------EndPath +Path 3 0 0 153 -609 +Curve 170 -489 140 -376 +Curve 108 -260 62 -151 +Curve 58 -142 53 -132 +Curve 5 -27 -75 54 +Curve -174 154 -299 95 +Curve -335 78 -335 65 +<-------EndPath +Path 3 0 -1 -335 65 +Curve -340 63 -344 61 +<-------EndPath +Path 3 -1 0 -344 61 +Curve -347 69 -349 76 +Curve -396 213 -443 349 +Curve -468 422 -487 512 +Curve -489 520 -490 527 +Curve -493 534 -495 541 +Curve -496 544 -496 547 +Curve -497 549 -497 550 +Curve -498 551 -498 552 +Curve -498 553 -498 554 +Curve -499 555 -499 556 +Curve -499 558 -499 559 +Curve -515 620 -521 684 +Curve -522 695 -522 705 +Curve -563 817 -603 929 +Curve -614 961 -624 992 +Curve -676 1145 -749 1288 +Curve -799 1385 -859 1476 +<-------EndPath +Path 3 -1 1 -859 1476 +Curve -820 1509 -781 1542 +<-------EndPath +Path 3 2 1 -781 1542 +Curve -731 1578 -667 1610 +Curve -555 1664 -442 1717 +<-------EndPath +Path 3 -1 1 -442 1717 +Curve -392 1741 -341 1765 +Curve -316 1777 -290 1788 +<-------EndPath +Path 3 -1 0 -290 1788 +Curve -198 1657 -121 1505 +Curve -108 1477 -94 1448 +<-------EndPath +Path 3 3 1 -94 1448 +Curve -148 1355 -201 1261 +Curve -321 1050 -388 829 +Curve -457 597 -436 362 +<-------EndPath +Path 3 1 0 530 -324 +Curve 538 -361 546 -397 +Curve 548 -409 550 -420 +Curve 550 -421 550 -422 +Curve 557 -462 564 -502 +<-------EndPath +Path -1 1 0 564 -502 +Curve 595 -417 569 -254 +Curve 563 -219 556 -183 +<-------EndPath +Path -1 0 0 556 -183 +Curve 531 -63 492 36 +<-------EndPath +Path -1 3 0 492 36 +Curve 479 67 466 97 +Curve 400 237 328 455 +<-------EndPath +Path -1 -1 0 328 455 +Curve 323 476 318 496 +<-------EndPath +Path -1 3 0 318 496 +Curve 319 521 319 546 +Curve 321 567 323 588 +Curve 329 647 346 707 +<-------EndPath +Path -1 3 1 346 707 +Curve 414 859 486 1000 +Curve 487 1001 487 1002 +Curve 589 1203 693 1371 +Curve 826 1586 665 1685 +Curve 661 1688 656 1690 +<-------EndPath +Path -1 2 -1 656 1690 +Curve 662 1690 668 1690 +<-------EndPath +Path -1 2 1 668 1690 +Curve 682 1692 695 1694 +Curve 750 1688 800 1663 +Curve 850 1637 905 1620 +Curve 961 1602 1010 1629 +Curve 1066 1660 1040 1719 +Curve 1016 1770 979 1814 +Curve 944 1855 895 1876 +Curve 844 1896 793 1916 +Curve 744 1930 695 1944 +Curve 641 1957 587 1970 +Curve 531 1980 474 1989 +Curve 420 1990 386 1949 +Curve 353 1907 341 1857 +<-------EndPath +Path -1 2 -1 341 1857 +Curve 338 1850 335 1842 +<-------EndPath +Path -1 3 1 335 1842 +Curve 274 1866 212 1889 +Curve 128 1816 59 1710 +Curve 47 1690 35 1670 +Curve -15 1584 -65 1498 +<-------EndPath +Path -1 -1 1 -65 1498 +Curve -80 1473 -94 1448 +<-------EndPath +Path 3 -1 0 -94 1448 +Curve -92 1444 -90 1440 +Curve -76 1461 -65 1498 +<-------EndPath +Path 3 0 0 492 36 +Curve 472 30 479 -35 +Curve 492 -161 521 -285 +Curve 526 -305 530 -324 +<-------EndPath +Path 1 0 -1 530 -324 +Curve 536 -303 542 -282 +Curve 555 -232 556 -183 +<-------EndPath +Path 1 -1 0 984 -806 +Curve 988 -807 992 -808 +Curve 1008 -811 1024 -813 +<-------EndPath +Path 0 0 0 762 -1511 +Curve 801 -1471 812 -1414 +<-------EndPath +Path -1 3 0 328 455 +Curve 323 471 318 486 +Curve 318 487 318 487 +Curve 318 492 318 496 +<-------EndPath +Path 3 3 1 346 707 +Curve 328 666 310 625 +<-------EndPath +Path 3 3 0 210 1201 +Curve 172 1259 182 1330 +<-------EndPath +Path 2 3 1 656 1690 +Curve 612 1714 567 1737 +Curve 461 1791 335 1842 +<-------EndPath +Path 0 0 0 -184 -1301 +Curve -225 -1296 -238 -1282 +Curve -241 -1275 -243 -1267 +Curve -240 -1260 -237 -1252 +Curve -236 -1250 -234 -1247 +Curve -221 -1231 -199 -1221 +<-------EndPath +Path 0 -1 0 148 -621 +Curve 50 -578 -66 -468 +Curve -184 -357 -275 -122 +Curve -310 -31 -344 61 +<-------EndPath +Path 0 0 0 -335 65 +Curve -333 61 -331 56 +<-------EndPath +Path 3 3 0 -113 335 +Curve -102 485 -241 608 +<-------EndPath +Path 2 -1 1 -781 1542 +Curve -811 1584 -827 1637 +Curve -836 1668 -824 1701 +Curve -803 1750 -781 1798 +Curve -758 1844 -722 1882 +Curve -683 1915 -644 1947 +Curve -602 1976 -559 2004 +Curve -513 2034 -460 2045 +Curve -409 2052 -357 2059 +Curve -299 2062 -245 2040 +Curve -196 2019 -167 1973 +Curve -139 1926 -160 1907 +Curve -181 1888 -206 1891 +Curve -246 1888 -285 1884 +Curve -339 1873 -380 1840 +Curve -426 1803 -440 1748 +Curve -441 1733 -442 1717 +<-------EndPath +Path 3 3 0 -36 969 +Curve -37 1029 -57 1086 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 1168 -1867 +Curve 1045 -1871 922 -1875 +Curve 799 -1857 704 -1780 +Curve 686 -1764 667 -1747 +Curve 601 -1683 573 -1606 +Curve 520 -1729 576 -1836 +Curve 582 -1847 588 -1858 +Curve 638 -1952 708 -2034 +Curve 782 -2120 884 -2167 +Curve 908 -2176 932 -2185 +Curve 975 -2193 1018 -2201 +<-------EndPath +Path -1 1 0 939 -1538 +Curve 999 -1526 1059 -1514 +Curve 1090 -1506 1121 -1498 +Curve 1262 -1454 1373 -1373 +Curve 1484 -1291 1506 -1240 +Curve 1528 -1190 1491 -1099 +Curve 1454 -1009 1074 -882 +Curve 1054 -879 1034 -876 +<-------EndPath +Path -1 -1 0 1034 -876 +Curve 1009 -872 984 -868 +<-------EndPath +Path -1 1 0 984 -868 +Curve 925 -859 866 -850 +<-------EndPath +Path -1 0 0 866 -850 +Curve 835 -849 804 -847 +Curve 724 -850 643 -852 +<-------EndPath +Path -1 -1 0 643 -852 +Curve 611 -851 579 -849 +Curve 562 -849 542 -832 +Curve 522 -811 502 -790 +Curve 488 -773 484 -756 +Curve 482 -743 480 -730 +<-------EndPath +Path -1 1 0 480 -730 +Curve 478 -712 484 -698 +Curve 500 -673 515 -648 +<-------EndPath +Path -1 4 0 515 -648 +Curve 524 -634 533 -620 +Curve 540 -610 546 -600 +Curve 555 -582 564 -564 +<-------EndPath +Path -1 -1 0 564 -564 +Curve 566 -573 567 -581 +<-------EndPath +Path 0 1 -1 959 -1528 +Curve 956 -1530 953 -1532 +Curve 946 -1535 939 -1538 +<-------EndPath +Path 0 -1 0 939 -1538 +Curve 851 -1555 762 -1572 +<-------EndPath +Path 0 0 0 762 -1572 +Curve 801 -1532 812 -1475 +<-------EndPath +Path 1 0 -1 1222 -1389 +Curve 1328 -1370 1414 -1253 +Curve 1500 -1137 1358 -1048 +Curve 1215 -960 1068 -924 +Curve 930 -890 866 -850 +<-------EndPath +Path 0 1 -1 1222 -1389 +Curve 1194 -1410 1165 -1431 +Curve 1071 -1497 959 -1528 +<-------EndPath +Path 0 0 0 959 -1528 +Curve 1002 -1504 1023 -1456 +<-------EndPath +Path 1 1 0 1121 -1498 +Curve 1196 -1472 1222 -1389 +<-------EndPath +Path -1 -1 0 1043 -1994 +Curve 919 -2035 808 -1973 +Curve 708 -1917 630 -1832 +Curve 621 -1820 612 -1808 +Curve 546 -1720 573 -1606 +<-------EndPath +Path 0 0 0 390 -1595 +Curve 405 -1580 420 -1565 +Curve 434 -1543 438 -1514 +<-------EndPath +Path -1 0 0 230 -710 +Curve 258 -722 276 -735 +Curve 316 -762 334 -804 +Curve 338 -820 342 -836 +Curve 345 -857 334 -879 +Curve 323 -901 304 -917 +Curve 189 -949 -11 -1047 +Curve -295 -1186 -279 -1292 +Curve -276 -1315 -272 -1337 +Curve -269 -1347 -266 -1356 +Curve -246 -1412 -194 -1447 +Curve -114 -1501 -38 -1522 +Curve 27 -1539 92 -1555 +Curve 122 -1561 152 -1567 +Curve 155 -1567 157 -1567 +Curve 274 -1581 390 -1595 +Curve 414 -1596 437 -1596 +Curve 465 -1598 492 -1599 +Curve 520 -1598 548 -1597 +Curve 560 -1597 572 -1596 +Curve 625 -1592 678 -1588 +Curve 720 -1580 762 -1572 +<-------EndPath +Path 0 0 0 157 -1567 +Curve 185 -1546 191 -1514 +Curve 194 -1494 189 -1469 +<-------EndPath +Path -1 0 -1 643 -852 +Curve 619 -854 594 -856 +Curve 511 -834 473 -762 +Curve 468 -751 462 -739 +<-------EndPath +Path -1 1 -1 462 -739 +Curve 471 -735 480 -730 +<-------EndPath +Path 4 1 0 515 -648 +Curve 515 -635 514 -621 +Curve 513 -612 512 -603 +Curve 504 -548 495 -493 +<-------EndPath +Path 4 0 0 495 -493 +Curve 492 -482 489 -470 +Curve 475 -416 461 -361 +Curve 444 -289 426 -216 +Curve 416 -172 393 -164 +Curve 354 -153 314 -142 +Curve 225 -121 134 -115 +Curve 142 -131 149 -147 +Curve 177 -200 204 -252 +Curve 265 -359 274 -482 +Curve 282 -612 230 -710 +<-------EndPath +Path 4 -1 0 230 -710 +Curve 191 -697 152 -684 +Curve 150 -683 148 -682 +<-------EndPath +Path 4 0 -1 148 -682 +Curve 151 -677 153 -671 +<-------EndPath +Path 4 0 0 153 -671 +Curve 170 -551 140 -437 +Curve 108 -321 62 -212 +Curve 58 -203 53 -193 +Curve 5 -88 -75 -7 +Curve -174 92 -299 33 +Curve -335 16 -335 3 +<-------EndPath +Path 4 0 -1 -335 3 +Curve -340 2 -344 0 +<-------EndPath +Path 4 -1 0 -344 0 +Curve -347 8 -349 15 +Curve -396 152 -443 288 +Curve -460 346 -476 404 +Curve -482 427 -487 450 +Curve -488 452 -488 454 +Curve -489 460 -490 466 +Curve -493 473 -495 480 +Curve -496 483 -496 486 +Curve -497 488 -497 489 +Curve -498 490 -498 491 +Curve -498 492 -498 493 +Curve -499 494 -499 495 +Curve -499 497 -499 498 +Curve -503 515 -507 531 +Curve -513 569 -519 607 +<-------EndPath +Path 4 -1 1 -519 607 +Curve -519 607 -518 607 +Curve -515 610 -512 613 +Curve -508 740 -459 841 +Curve -408 947 -388 1064 +Curve -385 1083 -381 1102 +<-------EndPath +Path 4 4 1 -381 1102 +Curve -368 1202 -377 1305 +Curve -385 1382 -392 1459 +<-------EndPath +Path 4 3 1 -392 1459 +Curve -397 1507 -402 1554 +Curve -405 1613 -407 1672 +<-------EndPath +Path 4 -1 1 -407 1672 +Curve -407 1673 -407 1674 +Curve -404 1727 -393 1772 +Curve -352 1785 -311 1797 +<-------EndPath +Path 4 3 1 -311 1797 +Curve -218 1821 -134 1826 +Curve -12 1830 136 1820 +<-------EndPath +Path 4 -1 1 136 1820 +Curve 138 1820 139 1819 +Curve 288 1808 261 1685 +Curve 236 1574 234 1464 +Curve 234 1463 234 1462 +<-------EndPath +Path 4 4 1 234 1462 +Curve 234 1452 234 1442 +Curve 234 1321 245 1198 +Curve 255 1077 273 958 +Curve 292 835 286 714 +Curve 284 670 281 626 +Curve 281 621 281 615 +Curve 283 571 294 531 +Curve 295 528 296 525 +<-------EndPath +Path 4 4 0 296 525 +Curve 303 502 310 479 +<-------EndPath +Path 4 2 1 310 479 +Curve 311 477 311 474 +Curve 313 471 315 467 +<-------EndPath +Path 4 -1 0 315 467 +Curve 316 461 317 454 +Curve 318 445 318 435 +Curve 318 431 318 426 +Curve 318 426 318 425 +Curve 322 415 325 404 +Curve 327 399 328 394 +Curve 400 176 466 36 +Curve 479 6 492 -25 +<-------EndPath +Path 4 0 0 492 -25 +Curve 472 -31 479 -96 +Curve 492 -222 521 -346 +Curve 526 -366 530 -385 +<-------EndPath +Path 4 1 0 530 -385 +Curve 538 -422 546 -459 +Curve 548 -471 550 -482 +Curve 550 -483 550 -483 +Curve 557 -524 564 -564 +<-------EndPath +Path -1 1 0 564 -564 +Curve 595 -478 569 -316 +Curve 563 -280 556 -244 +<-------EndPath +Path -1 0 0 556 -244 +Curve 531 -125 492 -25 +<-------EndPath +Path 1 0 -1 462 -739 +Curve 461 -736 460 -732 +Curve 430 -652 466 -565 +Curve 481 -529 495 -493 +<-------EndPath +Path 1 0 -1 530 -385 +Curve 536 -364 542 -343 +Curve 555 -294 556 -244 +<-------EndPath +Path -1 1 0 1034 -876 +Curve 1013 -873 992 -870 +Curve 988 -869 984 -868 +<-------EndPath +Path 4 4 1 218 626 +Curve 214 595 209 564 +Curve 207 548 204 531 +Curve 200 493 195 454 +Curve 192 429 189 404 +<-------EndPath +Path -1 -1 0 328 394 +Curve 327 399 326 404 +Curve 322 420 318 435 +<-------EndPath +Path -1 2 0 315 467 +Curve 314 469 313 471 +Curve 312 475 310 479 +<-------EndPath +Path -1 4 1 310 479 +Curve 310 590 375 692 +Curve 439 795 471 912 +Curve 502 1030 475 1151 +Curve 447 1275 360 1367 +Curve 288 1443 234 1462 +<-------EndPath +Path 3 -1 1 -311 1797 +Curve -386 1907 -308 2009 +Curve -291 2022 -273 2035 +Curve -163 2087 -39 2082 +Curve 87 2075 215 2079 +Curve 361 2085 410 1967 +Curve 440 1897 368 1899 +Curve 228 1901 137 1829 +<-------EndPath +Path 3 -1 -1 137 1829 +Curve 137 1825 136 1820 +<-------EndPath +Path 0 0 0 -184 -1362 +Curve -225 -1357 -238 -1344 +Curve -241 -1336 -243 -1328 +Curve -240 -1321 -237 -1314 +Curve -236 -1312 -234 -1309 +Curve -221 -1292 -199 -1282 +<-------EndPath +Path 0 -1 0 148 -682 +Curve 50 -639 -66 -529 +Curve -184 -418 -275 -183 +Curve -310 -92 -344 0 +<-------EndPath +Path 4 4 0 -163 298 +Curve -159 352 -174 404 +Curve -185 429 -195 454 +Curve -216 493 -250 531 +Curve -270 551 -290 571 +<-------EndPath +Path -1 -1 0 -519 607 +Curve -520 609 -520 611 +<-------EndPath +Path -1 2 1 -520 611 +Curve -520 619 -520 626 +<-------EndPath +Path -1 2 -1 -520 626 +Curve -521 626 -521 626 +Curve -521 625 -521 623 +Curve -521 623 -521 622 +Curve -521 617 -520 611 +<-------EndPath +Path -1 -1 1 -518 607 +Curve -519 607 -519 607 +<-------EndPath +Path 4 -1 1 -381 1102 +Curve -519 1126 -483 1262 +Curve -464 1316 -445 1369 +<-------EndPath +Path 4 3 1 -445 1369 +Curve -422 1419 -392 1459 +<-------EndPath +Path 3 -1 1 -445 1369 +Curve -594 1379 -558 1505 +Curve -543 1561 -502 1603 +Curve -458 1649 -407 1672 +<-------EndPath +Path 0 0 0 -335 3 +Curve -333 -1 -331 -5 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 0 1168 -1867 +Curve 1045 -1871 922 -1875 +Curve 799 -1857 704 -1780 +Curve 686 -1764 667 -1747 +Curve 601 -1683 573 -1606 +Curve 520 -1729 576 -1836 +Curve 582 -1847 588 -1858 +Curve 638 -1952 708 -2034 +Curve 782 -2120 884 -2167 +Curve 908 -2176 932 -2185 +Curve 975 -2193 1018 -2201 +<-------EndPath +Path -1 1 0 939 -1538 +Curve 999 -1526 1059 -1514 +Curve 1090 -1506 1121 -1498 +Curve 1262 -1454 1373 -1373 +Curve 1484 -1291 1506 -1240 +Curve 1528 -1190 1491 -1099 +Curve 1454 -1009 1074 -882 +Curve 1054 -879 1034 -876 +<-------EndPath +Path -1 -1 0 1034 -876 +Curve 1009 -872 984 -868 +<-------EndPath +Path -1 1 0 984 -868 +Curve 925 -859 866 -850 +<-------EndPath +Path -1 0 0 866 -850 +Curve 835 -849 804 -847 +Curve 724 -850 643 -852 +<-------EndPath +Path -1 -1 0 643 -852 +Curve 611 -851 579 -849 +Curve 562 -849 542 -832 +Curve 522 -811 502 -790 +Curve 488 -773 484 -756 +Curve 482 -743 480 -730 +<-------EndPath +Path -1 1 0 480 -730 +Curve 478 -712 484 -698 +Curve 500 -673 515 -648 +<-------EndPath +Path -1 4 0 515 -648 +Curve 524 -634 533 -620 +Curve 540 -610 546 -600 +Curve 555 -582 564 -564 +<-------EndPath +Path -1 -1 0 564 -564 +Curve 566 -573 567 -581 +<-------EndPath +Path 0 1 -1 959 -1528 +Curve 956 -1530 953 -1532 +Curve 946 -1535 939 -1538 +<-------EndPath +Path 0 -1 0 939 -1538 +Curve 851 -1555 762 -1572 +<-------EndPath +Path 0 0 0 762 -1572 +Curve 801 -1532 812 -1475 +<-------EndPath +Path 1 0 -1 1222 -1389 +Curve 1328 -1370 1414 -1253 +Curve 1500 -1137 1358 -1048 +Curve 1215 -960 1068 -924 +Curve 930 -890 866 -850 +<-------EndPath +Path 0 1 -1 1222 -1389 +Curve 1194 -1410 1165 -1431 +Curve 1071 -1497 959 -1528 +<-------EndPath +Path 0 0 0 959 -1528 +Curve 1002 -1504 1023 -1456 +<-------EndPath +Path 1 1 0 1121 -1498 +Curve 1196 -1472 1222 -1389 +<-------EndPath +Path -1 -1 0 1043 -1994 +Curve 919 -2035 808 -1973 +Curve 708 -1917 630 -1832 +Curve 621 -1820 612 -1808 +Curve 546 -1720 573 -1606 +<-------EndPath +Path 0 0 0 390 -1595 +Curve 405 -1580 420 -1565 +Curve 434 -1543 438 -1514 +<-------EndPath +Path -1 0 0 230 -710 +Curve 258 -722 276 -735 +Curve 316 -762 334 -804 +Curve 338 -820 342 -836 +Curve 345 -857 334 -879 +Curve 323 -901 304 -917 +Curve 189 -949 -11 -1047 +Curve -295 -1186 -279 -1292 +Curve -276 -1315 -272 -1337 +Curve -269 -1347 -266 -1356 +Curve -246 -1412 -194 -1447 +Curve -114 -1501 -38 -1522 +Curve 27 -1539 92 -1555 +Curve 122 -1561 152 -1567 +Curve 155 -1567 157 -1567 +Curve 274 -1581 390 -1595 +Curve 414 -1596 437 -1596 +Curve 465 -1598 492 -1599 +Curve 520 -1598 548 -1597 +Curve 560 -1597 572 -1596 +Curve 625 -1592 678 -1588 +Curve 720 -1580 762 -1572 +<-------EndPath +Path 0 0 0 157 -1567 +Curve 185 -1546 191 -1514 +Curve 194 -1494 189 -1469 +<-------EndPath +Path -1 0 -1 643 -852 +Curve 619 -854 594 -856 +Curve 511 -834 473 -762 +Curve 468 -751 462 -739 +<-------EndPath +Path -1 1 -1 462 -739 +Curve 471 -735 480 -730 +<-------EndPath +Path 4 1 0 515 -648 +Curve 515 -635 514 -621 +Curve 513 -612 512 -603 +Curve 504 -548 495 -493 +<-------EndPath +Path 4 0 0 495 -493 +Curve 492 -482 489 -470 +Curve 475 -416 461 -361 +Curve 444 -289 426 -216 +Curve 416 -172 393 -164 +Curve 354 -153 314 -142 +Curve 225 -121 134 -115 +Curve 142 -131 149 -147 +Curve 177 -200 204 -252 +Curve 265 -359 274 -482 +Curve 282 -612 230 -710 +<-------EndPath +Path 4 -1 0 230 -710 +Curve 191 -697 152 -684 +Curve 150 -683 148 -682 +<-------EndPath +Path 4 0 -1 148 -682 +Curve 151 -677 153 -671 +<-------EndPath +Path 4 0 0 153 -671 +Curve 170 -551 140 -437 +Curve 108 -321 62 -212 +Curve 58 -203 53 -193 +Curve 5 -88 -75 -7 +Curve -174 92 -299 33 +Curve -335 16 -335 3 +<-------EndPath +Path 4 0 -1 -335 3 +Curve -340 2 -344 0 +<-------EndPath +Path 4 -1 0 -344 0 +Curve -347 8 -349 15 +Curve -396 152 -443 288 +Curve -460 346 -476 404 +Curve -482 427 -487 450 +Curve -488 452 -488 454 +Curve -489 460 -490 466 +Curve -493 473 -495 480 +Curve -496 483 -496 486 +Curve -497 488 -497 489 +Curve -498 490 -498 491 +Curve -498 492 -498 493 +Curve -499 494 -499 495 +Curve -499 497 -499 498 +Curve -503 515 -507 531 +Curve -512 558 -516 584 +<-------EndPath +Path 4 -1 -1 -516 584 +Curve -513 584 -509 584 +<-------EndPath +Path 4 4 1 -509 584 +Curve -504 570 -499 556 +<-------EndPath +Path 1 0 -1 462 -739 +Curve 461 -736 460 -732 +Curve 430 -652 466 -565 +Curve 481 -529 495 -493 +<-------EndPath +Path 1 0 -1 530 -385 +Curve 536 -364 542 -343 +Curve 555 -294 556 -244 +<-------EndPath +Path 1 -1 0 556 -244 +Curve 563 -280 569 -316 +Curve 595 -478 564 -564 +<-------EndPath +Path 1 4 0 564 -564 +Curve 557 -524 550 -483 +Curve 550 -483 550 -482 +Curve 548 -471 546 -459 +Curve 538 -422 530 -385 +<-------EndPath +Path 0 4 0 530 -385 +Curve 526 -366 521 -346 +Curve 492 -222 479 -96 +Curve 472 -31 492 -25 +<-------EndPath +Path 0 -1 0 492 -25 +Curve 531 -125 556 -244 +<-------EndPath +Path -1 1 0 1034 -876 +Curve 1013 -873 992 -870 +Curve 988 -869 984 -868 +<-------EndPath +Path 4 -1 0 315 467 +Curve 316 461 317 454 +Curve 318 445 318 435 +Curve 318 431 318 426 +Curve 318 426 318 425 +Curve 322 415 325 404 +Curve 327 399 328 394 +Curve 400 176 466 36 +Curve 479 6 492 -25 +<-------EndPath +Path -1 -1 0 328 394 +Curve 327 399 326 404 +Curve 322 420 318 435 +<-------EndPath +Path 2 4 0 315 467 +Curve 313 471 311 474 +Curve 311 477 310 479 +<-------EndPath +Path 2 -1 0 310 479 +Curve 312 475 313 471 +Curve 314 469 315 467 +<-------EndPath +Path 4 4 0 310 479 +Curve 303 502 296 525 +Curve 295 528 294 531 +Curve 291 547 287 562 +<-------EndPath +Path 4 4 1 287 562 +Curve 278 573 269 584 +Curve 231 651 206 729 +Curve 178 817 166 916 +Curve 154 1015 141 1113 +Curve 140 1127 138 1141 +<-------EndPath +Path 4 -1 1 138 1141 +Curve 202 1159 197 1275 +Curve 188 1372 179 1468 +Curve 174 1499 220 1499 +Curve 241 1499 262 1498 +<-------EndPath +Path 4 3 1 262 1498 +Curve 336 1495 410 1492 +Curve 508 1489 606 1486 +Curve 637 1486 651 1474 +Curve 652 1457 653 1440 +<-------EndPath +Path 4 -1 1 653 1440 +Curve 659 1292 665 1143 +Curve 661 1046 657 948 +Curve 649 851 593 770 +Curve 536 689 448 651 +Curve 358 611 314 534 +<-------EndPath +Path 4 -1 0 314 534 +Curve 312 507 310 479 +<-------EndPath +Path -1 4 1 138 1141 +Curve 130 1221 130 1302 +Curve 133 1403 135 1503 +Curve 139 1597 127 1690 +Curve 115 1768 87 1828 +Curve 32 1833 -23 1837 +<-------EndPath +Path -1 3 1 -23 1837 +Curve 4 1882 86 1891 +Curve 194 1902 193 2011 +Curve 193 2024 179 2039 +Curve 175 2043 170 2046 +Curve 162 2052 154 2057 +Curve 126 2074 93 2079 +Curve 0 2083 -93 2086 +Curve -189 2076 -284 2065 +Curve -380 2049 -460 2012 +Curve -525 1982 -561 1929 +Curve -612 1855 -543 1770 +<-------EndPath +Path -1 4 1 -543 1770 +Curve -599 1752 -637 1726 +Curve -610 1665 -582 1604 +Curve -555 1530 -528 1456 +Curve -505 1383 -496 1306 +Curve -484 1212 -493 1117 +Curve -504 1025 -515 933 +Curve -527 839 -531 747 +Curve -535 663 -509 584 +<-------EndPath +Path -1 3 1 653 1440 +Curve 726 1338 835 1376 +Curve 943 1413 914 1456 +Curve 884 1497 803 1575 +Curve 776 1611 691 1647 +Curve 683 1651 674 1655 +Curve 628 1678 581 1701 +Curve 492 1744 394 1755 +Curve 273 1768 259 1651 +Curve 248 1568 262 1498 +<-------EndPath +Path 0 0 0 -184 -1362 +Curve -225 -1357 -238 -1344 +Curve -241 -1336 -243 -1328 +Curve -240 -1321 -237 -1314 +Curve -236 -1312 -234 -1309 +Curve -221 -1292 -199 -1282 +<-------EndPath +Path 0 -1 0 148 -682 +Curve 50 -639 -66 -529 +Curve -184 -418 -275 -183 +Curve -310 -92 -344 0 +<-------EndPath +Path 4 4 0 -204 324 +Curve -200 378 -216 430 +Curve -227 455 -237 480 +Curve -258 519 -292 557 +Curve -306 571 -319 584 +Curve -326 591 -332 597 +<-------EndPath +Path 3 4 1 -23 1837 +Curve -38 1839 -53 1841 +Curve -159 1835 -265 1829 +Curve -368 1808 -471 1787 +Curve -507 1779 -543 1770 +<-------EndPath +Path 4 4 1 -543 1770 +Curve -540 1766 -537 1762 +<-------EndPath +Path 0 0 0 -335 3 +Curve -333 -1 -331 -5 +<-------EndPath +!======EndShape +=======BeginShape +Path 0 -1 -1 22 -320 +Curve 15 -320 8 -320 +<-------EndPath +Path 0 -1 0 8 -320 +Curve 8 -275 8 -230 +<-------EndPath +Path 0 2 1 8 -230 +Curve 15 -275 22 -320 +<-------EndPath +Path -1 2 -1 22 -320 +Curve 1609 -320 3195 -320 +<-------EndPath +Path -1 0 -1 3195 -320 +Curve 3285 -320 3375 -320 +<-------EndPath +Path -1 1 -1 3375 -320 +Curve 4296 -320 5216 -320 +<-------EndPath +Path -1 2 -1 5216 -320 +Curve 5854 -320 6491 -320 +<-------EndPath +Path -1 4 -1 6491 -320 +Curve 6552 -320 6612 -320 +<-------EndPath +Path -1 2 -1 6612 -320 +Curve 7167 -320 7721 -320 +Curve 7721 1266 7721 2851 +<-------EndPath +Path -1 6 -1 7721 2851 +Curve 7721 3049 7721 3247 +<-------EndPath +Path -1 5 -1 7721 3247 +Curve 7721 4020 7721 4793 +<-------EndPath +Path -1 10 -1 7721 4793 +Curve 7721 4860 7721 4927 +<-------EndPath +Path -1 5 -1 7721 4927 +Curve 7721 5315 7721 5702 +Curve 7721 5733 7721 5764 +<-------EndPath +Path -1 9 -1 7721 5764 +Curve 7721 5898 7721 6032 +<-------EndPath +Path -1 11 -1 7721 6032 +Curve 7721 6197 7721 6362 +Curve 6171 6362 4621 6362 +<-------EndPath +Path -1 12 -1 4621 6362 +Curve 4624 6362 4626 6362 +Curve 4557 6362 4488 6362 +<-------EndPath +Path -1 13 -1 4488 6362 +Curve 4324 6362 4159 6362 +<-------EndPath +Path -1 12 -1 4159 6362 +Curve 3802 6362 3444 6362 +Curve 1726 6362 8 6362 +<-------EndPath +Path -1 12 0 8 6362 +Curve 8 6308 8 6254 +<-------EndPath +Path -1 11 0 8 6254 +Curve 8 6032 8 5809 +<-------EndPath +Path -1 15 0 8 5809 +Curve 8 5633 8 5457 +<-------EndPath +Path -1 5 0 8 5457 +Curve 8 5457 8 5456 +Curve 8 5041 8 4626 +<-------EndPath +Path -1 10 0 8 4626 +Curve 8 4520 8 4414 +<-------EndPath +Path -1 5 0 8 4414 +Curve 8 3806 8 3197 +<-------EndPath +Path -1 6 0 8 3197 +Curve 8 2946 8 2695 +<-------EndPath +Path -1 2 0 8 2695 +Curve 8 1233 8 -230 +<-------EndPath +Path 0 2 1 3195 -320 +Curve 3200 -255 3195 -184 +<-------EndPath +Path 0 1 -1 3195 -184 +Curve 3289 -244 3375 -320 +<-------EndPath +Path 2 3 -1 5136 -240 +Curve 5136 -237 5136 -234 +Curve 5135 -237 5134 -239 +Curve 5135 -240 5136 -240 +<-------EndPath +Path 1 2 1 5146 824 +Curve 4942 433 4910 183 +Curve 4866 -154 5133 -240 +Curve 5135 -241 5136 -241 +Curve 5215 -265 5322 -268 +Curve 5269 -294 5216 -320 +<-------EndPath +Path 4 2 1 6950 2817 +Curve 6780 1427 6703 1302 +Curve 6487 953 6725 637 +Curve 6852 468 6959 347 +Curve 6827 464 6617 459 +Curve 6593 73 6612 -316 +Curve 6612 -318 6612 -320 +<-------EndPath +Path 4 2 -1 6695 2810 +Curve 6823 2814 6950 2817 +<-------EndPath +Path 5 10 -1 7721 4927 +Curve 7619 4925 7516 4923 +Curve 6847 4910 6186 4887 +Curve 5951 4878 5715 4869 +Curve 5183 4849 4651 4828 +Curve 4126 4809 3601 4789 +Curve 2617 4746 1633 4703 +Curve 821 4665 8 4626 +<-------EndPath +Path 5 9 -1 4012 5632 +Curve 5463 5686 6913 5740 +Curve 7317 5752 7721 5764 +<-------EndPath +Path 4 2 1 6491 -320 +Curve 6489 -71 6445 173 +Curve 6376 553 6473 942 +Curve 6540 1207 6695 2810 +<-------EndPath +Path 1 1 1 5146 824 +Curve 5146 825 5145 825 +<-------EndPath +Path 1 2 1 5145 825 +Curve 5153 839 5161 853 +Curve 5154 839 5146 824 +<-------EndPath +Path 1 2 1 3195 -184 +Curve 3176 62 3029 374 +Curve 4121 483 3578 976 +Curve 3406 1132 3318 1238 +Curve 3147 1443 3292 1458 +Curve 3245 1383 3535 1379 +Curve 3836 1374 4167 712 +Curve 4276 493 4420 431 +Curve 4711 307 5145 825 +<-------EndPath +Path 5 6 -1 3484 3874 +Curve 3665 3840 3851 3824 +Curve 2711 3577 1555 3767 +Curve 1415 3790 1274 3824 +Curve 1258 3839 1241 3853 +Curve 1222 3867 1202 3880 +Curve 1198 3872 1193 3863 +Curve 1211 3823 1243 3790 +Curve 1253 3779 1263 3767 +Curve 1425 3740 1586 3713 +Curve 1833 3669 2086 3644 +Curve 2149 3637 2188 3623 +Curve 3309 3646 4416 3824 +Curve 4422 3829 4427 3834 +Curve 4417 3839 4406 3843 +Curve 4098 3872 3790 3901 +Curve 5355 3868 6890 3880 +Curve 5147 4087 3482 3891 +Curve 3482 3874 3484 3874 +<-------EndPath +Path 8 2 -1 5324 2797 +Curve 5324 2796 5324 2794 +<-------EndPath +Path 8 2 1 5324 2794 +Curve 5305 2793 5286 2792 +<-------EndPath +Path 8 7 -1 5286 2792 +Curve 5286 2794 5285 2796 +<-------EndPath +Path 8 6 1 5285 2796 +Curve 5305 2797 5324 2797 +<-------EndPath +Path 2 6 1 5324 2797 +Curve 6523 2824 7721 2851 +<-------EndPath +Path 2 7 1 5285 2792 +Curve 5286 2792 5286 2792 +<-------EndPath +Path 6 7 -1 5285 2796 +Curve 5285 2794 5285 2792 +<-------EndPath +Path 6 2 1 5285 2792 +Curve 2647 2744 8 2695 +<-------EndPath +Path 5 7 -1 5203 3225 +Curve 5184 3225 5164 3225 +Curve 5164 3225 5164 3224 +<-------EndPath +Path 5 6 -1 5164 3224 +Curve 2586 3211 8 3197 +<-------EndPath +Path 6 7 -1 5164 3224 +Curve 5184 3225 5203 3225 +<-------EndPath +Path 6 5 -1 5203 3225 +Curve 5589 3229 5975 3232 +<-------EndPath +Path 6 14 -1 5975 3232 +Curve 5976 3231 5976 3229 +Curve 5977 3229 5977 3229 +Curve 5984 3231 5991 3232 +<-------EndPath +Path 6 5 -1 5991 3232 +Curve 6856 3240 7721 3247 +<-------EndPath +Path 5 14 -1 5991 3232 +Curve 5983 3232 5975 3232 +<-------EndPath +Path 10 5 -1 7721 4793 +Curve 6961 4730 6189 4701 +Curve 5423 4656 4657 4611 +Curve 3930 4566 3202 4520 +Curve 1921 4480 640 4440 +Curve 328 4427 15 4414 +Curve 12 4414 8 4414 +<-------EndPath +Path 5 15 -1 8 5457 +Curve 18 5458 27 5458 +Curve 1693 5530 3359 5602 +Curve 3576 5612 3793 5622 +<-------EndPath +Path 5 5 0 3793 5622 +Curve 3833 5599 3875 5579 +Curve 1942 5518 8 5456 +<-------EndPath +Path 16 17 0 3418 5910 +Curve 3419 5909 3420 5908 +<-------EndPath +Path 16 15 0 3420 5908 +Curve 3419 5908 3417 5908 +<-------EndPath +Path 16 11 0 3417 5908 +Curve 3418 5909 3418 5910 +<-------EndPath +Path 17 11 0 3418 5910 +Curve 3458 6101 3464 6334 +<-------EndPath +Path 17 16 0 3464 6334 +Curve 3465 6343 3465 6351 +<-------EndPath +Path 17 12 0 3465 6351 +Curve 3507 6323 3548 6294 +Curve 3557 6285 3566 6275 +<-------EndPath +Path 17 11 0 3566 6275 +Curve 3556 6106 3545 5936 +<-------EndPath +Path 17 16 0 3545 5936 +Curve 3544 5924 3543 5911 +Curve 3551 5911 3558 5911 +<-------EndPath +Path 17 9 0 3558 5911 +Curve 3687 5676 3926 5628 +<-------EndPath +Path 17 5 -1 3926 5628 +Curve 3860 5625 3793 5622 +<-------EndPath +Path 17 15 0 3793 5622 +Curve 3601 5730 3420 5908 +<-------EndPath +Path 11 16 0 3558 5911 +Curve 3552 5924 3545 5936 +<-------EndPath +Path 5 9 0 3926 5628 +Curve 3969 5630 4012 5632 +<-------EndPath +Path 13 12 -1 4273 6353 +Curve 4216 6358 4159 6362 +<-------EndPath +Path 13 12 -1 4488 6362 +Curve 4488 6360 4488 6358 +<-------EndPath +Path 13 11 0 4488 6358 +Curve 4381 6356 4273 6353 +<-------EndPath +Path 12 11 0 4273 6353 +Curve 3921 6345 3569 6336 +Curve 3568 6306 3566 6275 +<-------EndPath +Path 11 12 0 4488 6358 +Curve 4555 6360 4621 6362 +<-------EndPath +Path 16 12 0 3461 6353 +Curve 3463 6352 3465 6351 +<-------EndPath +Path 12 12 0 3461 6353 +Curve 3453 6358 3444 6362 +<-------EndPath +Path 16 12 -1 3461 6334 +Curve 3461 6344 3461 6353 +<-------EndPath +Path 16 11 0 3464 6334 +Curve 3463 6334 3461 6334 +<-------EndPath +Path 12 11 0 3461 6334 +Curve 1735 6294 8 6254 +<-------EndPath +Path 11 11 0 3418 5910 +Curve 3403 5925 3387 5940 +<-------EndPath +Path 11 15 0 3417 5908 +Curve 1713 5859 8 5809 +<-------EndPath +Path 11 9 0 7721 6032 +Curve 5640 5972 3558 5911 +<-------EndPath +Path 5 5 0 3875 5579 +Curve 5798 5641 7721 5702 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 -1 1 46 -2079 +Curve 79 -2083 112 -2087 +Curve 228 -2098 330 -2028 +Curve 433 -1961 484 -1849 +Curve 489 -1838 493 -1827 +Curve 519 -1763 527 -1697 +Curve 534 -1673 541 -1649 +Curve 542 -1649 542 -1648 +Curve 546 -1671 549 -1693 +Curve 549 -1694 549 -1695 +Curve 559 -1789 530 -1883 +Curve 492 -1998 453 -2112 +Curve 410 -2233 291 -2302 +Curve 212 -2350 127 -2385 +Curve 24 -2429 -85 -2432 +<-------EndPath +Path 0 -1 1 873 -1534 +Curve 870 -1535 866 -1536 +Curve 772 -1574 675 -1595 +Curve 607 -1608 538 -1620 +Curve 533 -1621 528 -1622 +Curve 438 -1633 348 -1644 +Curve 266 -1654 174 -1646 +<-------EndPath +Path 0 0 1 174 -1646 +Curve 240 -1626 258 -1565 +<-------EndPath +Path 1 -1 1 1338 -1166 +Curve 1313 -1230 1244 -1299 +Curve 1231 -1312 1217 -1325 +Curve 1211 -1331 1205 -1336 +Curve 1089 -1440 947 -1501 +Curve 910 -1518 873 -1534 +<-------EndPath +Path 1 0 1 873 -1534 +Curve 880 -1513 887 -1492 +<-------EndPath +Path 1 0 -1 887 -1492 +Curve 987 -1428 1064 -1339 +Curve 1102 -1294 1139 -1248 +Curve 1170 -1211 1220 -1085 +Curve 1269 -959 1027 -882 +Curve 784 -805 606 -793 +Curve 563 -791 527 -777 +Curve 523 -775 518 -773 +Curve 508 -774 497 -775 +Curve 495 -765 492 -754 +Curve 492 -754 491 -754 +Curve 465 -740 454 -716 +Curve 453 -719 452 -722 +Curve 447 -735 445 -713 +Curve 444 -690 443 -667 +Curve 443 -666 443 -664 +Curve 443 -659 443 -654 +Curve 442 -562 466 -503 +Curve 481 -468 495 -432 +<-------EndPath +Path 1 4 0 495 -432 +Curve 504 -487 512 -542 +Curve 513 -551 514 -559 +Curve 515 -573 515 -587 +<-------EndPath +Path 1 -1 0 515 -587 +Curve 500 -612 484 -636 +Curve 478 -651 480 -669 +<-------EndPath +Path 1 -1 -1 480 -669 +Curve 479 -670 478 -670 +<-------EndPath +Path 1 -1 1 478 -670 +Curve 480 -675 481 -679 +Curve 484 -688 486 -696 +Curve 489 -703 491 -709 +Curve 492 -711 493 -713 +Curve 503 -739 514 -750 +Curve 525 -761 536 -772 +Curve 555 -776 574 -780 +Curve 579 -779 583 -778 +Curve 588 -778 592 -777 +Curve 635 -774 678 -771 +Curve 965 -758 1196 -892 +Curve 1347 -981 1353 -1088 +<-------EndPath +Path 1 1 1 1353 -1088 +Curve 1355 -1126 1338 -1166 +<-------EndPath +Path -1 1 1 1338 -1166 +Curve 1437 -1148 1353 -1088 +<-------EndPath +Path 0 0 1 887 -1492 +Curve 890 -1473 893 -1453 +<-------EndPath +Path -1 -1 1 528 -1622 +Curve 529 -1635 529 -1647 +Curve 528 -1672 527 -1697 +Curve 501 -1763 448 -1814 +Curve 429 -1830 409 -1845 +Curve 306 -1916 183 -1938 +Curve 132 -1947 84 -1939 +<-------EndPath +Path 0 -1 1 174 -1646 +Curve 94 -1634 13 -1621 +<-------EndPath +Path 0 0 1 13 -1621 +Curve 76 -1591 116 -1531 +<-------EndPath +Path -1 0 -1 430 -722 +Curve 437 -722 444 -722 +Curve 436 -724 428 -726 +<-------EndPath +Path -1 1 -1 428 -726 +Curve 429 -724 430 -722 +<-------EndPath +Path 0 1 -1 430 -722 +Curve 377 -722 323 -722 +<-------EndPath +Path 0 -1 0 323 -722 +Curve 320 -718 317 -713 +Curve 301 -690 276 -673 +Curve 253 -661 230 -649 +<-------EndPath +Path 0 4 0 230 -649 +Curve 282 -551 274 -421 +Curve 265 -297 204 -190 +Curve 177 -138 149 -86 +Curve 142 -70 134 -54 +Curve 225 -59 314 -81 +Curve 354 -92 393 -103 +Curve 416 -111 426 -155 +Curve 443 -227 460 -299 +Curve 461 -300 461 -300 +Curve 475 -355 489 -409 +Curve 492 -421 495 -432 +<-------EndPath +Path -1 -1 1 491 -709 +Curve 486 -694 481 -679 +<-------EndPath +Path -1 4 0 515 -587 +Curve 524 -573 533 -558 +Curve 540 -549 546 -539 +Curve 553 -528 559 -516 +Curve 562 -509 564 -502 +<-------EndPath +Path -1 1 0 564 -502 +Curve 595 -417 569 -254 +Curve 563 -219 556 -183 +<-------EndPath +Path -1 0 0 556 -183 +Curve 531 -63 492 36 +<-------EndPath +Path -1 4 0 492 36 +Curve 479 67 466 97 +Curve 400 237 328 455 +<-------EndPath +Path -1 -1 0 328 455 +Curve 323 476 318 496 +<-------EndPath +Path -1 4 0 318 496 +Curve 319 521 319 546 +Curve 321 567 323 588 +Curve 339 732 412 874 +Curve 465 979 499 1089 +Curve 531 1193 546 1302 +Curve 566 1441 558 1575 +Curve 555 1611 511 1632 +<-------EndPath +Path -1 3 0 511 1632 +Curve 552 1669 751 1503 +Curve 974 1539 813 1696 +Curve 652 1852 449 1910 +Curve 246 1967 224 1686 +<-------EndPath +Path -1 3 -1 224 1686 +Curve 224 1683 223 1680 +<-------EndPath +Path -1 4 0 223 1680 +Curve 153 1694 83 1707 +Curve -33 1730 -49 1586 +Curve -61 1482 -90 1440 +Curve -106 1473 -121 1505 +Curve -198 1658 -291 1789 +Curve -308 1808 -324 1826 +Curve -350 1843 -375 1859 +Curve -419 1845 -462 1830 +Curve -485 1822 -507 1813 +<-------EndPath +Path -1 3 0 -507 1813 +Curve -442 1848 -383 1875 +Curve -319 1901 -255 1927 +Curve -234 1933 -225 1947 +Curve -222 1961 -243 2025 +Curve -285 2039 -340 2042 +Curve -366 2042 -392 2042 +Curve -459 2034 -526 2025 +Curve -705 1988 -859 1907 +Curve -1051 1806 -910 1657 +<-------EndPath +Path -1 4 0 -910 1657 +Curve -931 1636 -952 1614 +Curve -938 1591 -923 1568 +Curve -826 1434 -749 1288 +Curve -699 1191 -659 1089 +Curve -642 1041 -624 992 +Curve -575 844 -522 705 +Curve -522 695 -521 684 +Curve -515 620 -499 559 +Curve -499 558 -499 556 +Curve -499 555 -498 554 +Curve -498 553 -498 552 +Curve -498 551 -497 550 +Curve -497 549 -496 547 +Curve -496 544 -495 541 +Curve -493 534 -490 527 +Curve -489 520 -487 512 +Curve -468 422 -443 349 +Curve -396 213 -349 76 +Curve -347 69 -344 61 +<-------EndPath +Path -1 0 0 -344 61 +Curve -310 -31 -275 -122 +Curve -184 -357 -66 -468 +Curve 50 -578 148 -621 +<-------EndPath +Path -1 4 0 148 -621 +Curve 150 -622 152 -622 +Curve 191 -636 230 -649 +<-------EndPath +Path -1 0 1 323 -722 +Curve 342 -779 299 -808 +Curve 256 -838 230 -846 +Curve 165 -864 81 -896 +Curve -81 -958 -266 -1062 +Curve -447 -1164 -443 -1319 +Curve -443 -1324 -443 -1328 +Curve -435 -1471 -209 -1557 +Curve -179 -1568 -148 -1579 +Curve -68 -1600 13 -1621 +<-------EndPath +Path 4 0 -1 148 -621 +Curve 151 -615 153 -609 +<-------EndPath +Path 4 0 0 153 -609 +Curve 170 -489 140 -376 +Curve 108 -260 62 -151 +Curve 58 -142 53 -132 +Curve 5 -27 -75 54 +Curve -174 154 -299 95 +Curve -335 78 -335 65 +<-------EndPath +Path 4 0 -1 -335 65 +Curve -340 63 -344 61 +<-------EndPath +Path 1 4 0 564 -502 +Curve 557 -462 550 -422 +Curve 550 -421 550 -420 +Curve 548 -409 546 -397 +Curve 538 -361 530 -324 +<-------EndPath +Path 1 0 -1 530 -324 +Curve 536 -303 542 -282 +Curve 555 -232 556 -183 +<-------EndPath +Path 0 4 0 530 -324 +Curve 526 -305 522 -286 +Curve 522 -286 521 -285 +Curve 492 -161 479 -35 +Curve 472 30 492 36 +<-------EndPath +Path 1 0 -1 428 -726 +Curve 376 -724 323 -722 +<-------EndPath +Path -1 4 0 328 455 +Curve 323 471 318 486 +Curve 318 487 318 487 +Curve 318 492 318 496 +<-------EndPath +Path 4 4 0 -90 1440 +Curve -49 1346 -18 1248 +Curve -12 1226 -5 1204 +Curve 11 1147 27 1089 +Curve 55 994 83 899 +Curve 98 845 112 790 +Curve 124 738 136 685 +Curve 143 659 149 633 +Curve 149 590 148 547 +<-------EndPath +Path 4 4 0 88 1212 +Curve 69 1241 63 1274 +Curve 56 1306 61 1342 +<-------EndPath +Path 2 3 -1 375 1656 +Curve 375 1660 375 1664 +<-------EndPath +Path 2 3 0 375 1664 +Curve 393 1661 411 1658 +<-------EndPath +Path 2 4 0 411 1658 +Curve 393 1657 375 1656 +<-------EndPath +Path 3 4 0 375 1656 +Curve 299 1668 223 1680 +<-------EndPath +Path 3 4 0 511 1632 +Curve 494 1638 476 1644 +Curve 451 1650 426 1655 +Curve 419 1657 411 1658 +<-------EndPath +Path 0 0 1 -209 -1557 +Curve -141 -1528 -100 -1466 +<-------EndPath +Path 0 0 1 -355 -1352 +Curve -397 -1340 -402 -1319 +Curve -408 -1298 -376 -1267 +<-------EndPath +Path 4 4 0 -235 347 +Curve -223 497 -362 620 +<-------EndPath +Path 4 3 0 -910 1657 +Curve -910 1658 -910 1658 +Curve -854 1703 -771 1727 +Curve -647 1763 -524 1807 +Curve -516 1810 -507 1813 +<-------EndPath +Path 4 4 0 -157 980 +Curve -158 1036 -175 1089 +<-------EndPath +!======EndShape +=======BeginShape +Path -1 0 0 -234 -1074 +Curve -187 -1080 -139 -1085 +Curve -53 -1093 37 -1081 +Curve 129 -1062 220 -1043 +Curve 262 -1035 304 -1026 +<-------EndPath +Path -1 -1 0 304 -1026 +Curve 396 -1045 409 -989 +<-------EndPath +Path -1 0 0 409 -989 +Curve 411 -989 413 -988 +Curve 430 -981 447 -973 +<-------EndPath +Path -1 -1 0 447 -973 +Curve 514 -961 534 -929 +<-------EndPath +Path -1 0 0 534 -929 +Curve 570 -908 606 -886 +<-------EndPath +Path -1 -1 0 606 -886 +Curve 647 -868 662 -848 +<-------EndPath +Path -1 0 0 662 -848 +Curve 775 -761 758 -609 +Curve 737 -440 596 -372 +Curve 514 -333 435 -326 +Curve 384 -328 333 -330 +<-------EndPath +Path -1 0 -1 333 -330 +Curve 330 -331 327 -331 +<-------EndPath +Path -1 0 0 327 -331 +Curve 327 -331 326 -331 +Curve 324 -332 322 -332 +Curve 248 -336 174 -340 +Curve 108 -333 79 -290 +<-------EndPath +Path -1 2 0 79 -290 +Curve 111 -296 143 -301 +Curve 248 -321 314 -300 +Curve 356 -290 397 -279 +Curve 400 -279 403 -278 +Curve 416 -277 429 -275 +Curve 460 -273 490 -270 +<-------EndPath +Path -1 6 0 490 -270 +Curve 556 -315 590 -226 +<-------EndPath +Path -1 5 0 590 -226 +Curve 597 -219 603 -212 +<-------EndPath +Path -1 2 0 603 -212 +Curve 605 -210 607 -207 +Curve 618 -191 628 -175 +Curve 645 -140 662 -104 +<-------EndPath +Path -1 7 0 662 -104 +Curve 687 -120 712 -136 +Curve 711 -125 718 -115 +Curve 748 -74 787 -44 +Curve 773 -45 759 -46 +Curve 750 -45 741 -43 +<-------EndPath +Path -1 6 0 741 -43 +Curve 783 64 749 165 +Curve 740 190 725 205 +<-------EndPath +Path -1 -1 0 725 205 +Curve 728 227 731 248 +<-------EndPath +Path -1 0 0 606 -886 +Curve 626 -873 645 -860 +Curve 649 -857 653 -854 +Curve 658 -851 662 -848 +<-------EndPath +Path 0 0 0 662 -848 +Curve 691 -806 607 -752 +<-------EndPath +Path 0 1 -1 607 -752 +Curve 650 -716 692 -679 +Curve 673 -646 654 -613 +Curve 618 -575 582 -537 +Curve 522 -495 462 -453 +Curve 331 -399 75 -389 +Curve 63 -377 50 -365 +Curve 20 -331 4 -293 +Curve -11 -260 -15 -224 +Curve -16 -218 -17 -211 +Curve -18 -202 -18 -193 +Curve -14 -192 -10 -191 +Curve 14 -129 68 -103 +Curve 95 -90 129 -86 +<-------EndPath +Path 0 3 0 129 -86 +Curve 135 -110 141 -134 +<-------EndPath +Path 0 2 0 141 -134 +Curve 80 -170 56 -224 +<-------EndPath +Path 0 2 -1 56 -224 +Curve 56 -224 55 -224 +<-------EndPath +Path 0 0 0 55 -224 +Curve 55 -209 54 -193 +Curve 55 -184 56 -174 +<-------EndPath +Path -1 0 0 447 -973 +Curve 490 -952 533 -930 +Curve 534 -930 534 -929 +<-------EndPath +Path 0 0 0 534 -929 +Curve 559 -890 510 -821 +<-------EndPath +Path 0 1 -1 510 -821 +Curve 560 -790 607 -752 +<-------EndPath +Path 1 1 0 607 -752 +Curve 594 -745 580 -737 +<-------EndPath +Path 1 0 -1 510 -821 +Curve 452 -855 393 -888 +Curve 323 -923 249 -948 +Curve 77 -1005 -99 -1019 +Curve -237 -1013 -375 -1007 +Curve -390 -1005 -404 -1002 +<-------EndPath +Path 1 1 0 -404 -1002 +Curve -407 -977 -410 -952 +<-------EndPath +Path 1 0 -1 14 -709 +Curve -8 -679 -42 -689 +Curve -104 -706 -101 -767 +Curve -101 -773 -100 -778 +Curve -133 -722 -197 -705 +Curve -216 -710 -234 -715 +Curve -293 -769 -250 -846 +Curve -237 -868 -224 -889 +Curve -224 -912 -216 -933 +Curve -212 -941 -208 -949 +Curve -206 -951 -204 -953 +Curve -199 -956 -194 -958 +Curve -186 -955 -178 -952 +Curve -163 -890 -178 -827 +Curve -180 -820 -182 -812 +Curve -164 -844 -133 -871 +Curve -105 -889 -77 -906 +Curve -54 -905 -31 -904 +Curve -13 -859 -40 -826 +Curve -39 -806 -38 -785 +Curve -39 -776 -40 -766 +Curve -39 -764 -38 -761 +Curve -35 -760 -32 -758 +Curve -3 -820 56 -857 +Curve 63 -860 69 -863 +Curve 83 -861 96 -859 +Curve 140 -827 92 -789 +Curve 46 -756 14 -709 +<-------EndPath +Path 0 0 0 333 -330 +Curve 330 -331 327 -331 +<-------EndPath +Path 2 2 0 397 -279 +Curve 385 -279 375 -263 +Curve 354 -230 340 -230 +Curve 326 -232 311 -233 +Curve 266 -239 220 -245 +Curve 143 -255 101 -222 +Curve 101 -251 82 -283 +<-------EndPath +Path 2 3 0 141 -134 +Curve 143 -134 144 -133 +Curve 160 -123 175 -113 +Curve 176 -113 176 -112 +<-------EndPath +Path 2 4 0 176 -112 +Curve 191 -105 205 -97 +Curve 242 -78 278 -59 +<-------EndPath +Path 2 3 0 278 -59 +Curve 349 -16 410 43 +<-------EndPath +Path 2 6 0 410 43 +Curve 410 34 409 25 +<-------EndPath +Path 2 2 0 409 25 +Curve 406 24 403 23 +<-------EndPath +Path 2 0 0 79 -290 +Curve 63 -268 57 -237 +Curve 56 -231 55 -224 +<-------EndPath +Path 3 1 0 129 -86 +Curve 114 -53 79 -43 +Curve 78 -43 76 -42 +Curve 48 -38 20 -33 +Curve -72 -28 -129 -96 +Curve -132 -100 -135 -103 +<-------EndPath +Path 3 0 0 -135 -103 +Curve -149 -125 -162 -146 +<-------EndPath +Path 3 2 0 -162 -146 +Curve -167 -141 -171 -135 +<-------EndPath +Path 3 7 0 -171 -135 +Curve -179 -125 -187 -114 +<-------EndPath +Path 3 4 0 -187 -114 +Curve -189 -75 -180 -45 +Curve -170 -14 -150 8 +Curve -127 24 -103 39 +Curve -61 56 2 56 +Curve 20 55 37 54 +Curve 62 48 86 41 +Curve 167 5 176 -112 +<-------EndPath +Path 2 5 0 603 -212 +Curve 596 -213 588 -214 +<-------EndPath +Path 2 6 0 588 -214 +Curve 501 -225 469 -138 +Curve 450 -87 463 51 +<-------EndPath +Path 2 2 0 463 51 +Curve 528 90 571 163 +Curve 598 207 608 253 +<-------EndPath +Path 2 5 0 608 253 +Curve 627 271 633 297 +<-------EndPath +Path 2 -1 0 633 297 +Curve 654 260 674 223 +<-------EndPath +Path 2 6 0 674 223 +Curve 648 223 614 210 +<-------EndPath +Path 2 -1 0 614 210 +Curve 619 198 624 186 +<-------EndPath +Path 2 12 0 624 186 +Curve 603 170 593 178 +Curve 593 170 592 161 +Curve 589 59 551 -43 +<-------EndPath +Path 2 2 0 551 -43 +Curve 545 -41 539 -39 +<-------EndPath +Path 2 12 0 551 -43 +Curve 557 -46 563 -49 +<-------EndPath +Path 2 7 0 563 -49 +Curve 575 -54 589 -62 +Curve 627 -82 662 -104 +<-------EndPath +Path 6 5 -1 588 -214 +Curve 589 -220 590 -226 +<-------EndPath +Path 7 6 0 616 3 +Curve 649 -16 688 -29 +Curve 715 -36 741 -43 +<-------EndPath +Path 6 2 0 490 -270 +Curve 458 -230 426 -190 +Curve 397 -152 409 25 +<-------EndPath +Path 6 6 0 409 25 +Curve 438 35 463 51 +<-------EndPath +Path 2 6 0 463 51 +Curve 467 79 470 107 +<-------EndPath +Path 2 3 0 470 107 +Curve 477 115 483 123 +<-------EndPath +Path 2 4 0 483 123 +Curve 515 171 546 219 +<-------EndPath +Path 2 5 0 546 219 +Curve 560 226 574 232 +Curve 591 243 608 253 +<-------EndPath +Path 5 5 0 608 253 +Curve 615 290 611 327 +<-------EndPath +Path 5 -1 0 611 327 +Curve 622 312 633 297 +<-------EndPath +Path 0 0 0 409 -989 +Curve 417 -953 393 -888 +<-------EndPath +Path -1 0 0 304 -1026 +Curve 357 -1012 409 -989 +<-------EndPath +Path 0 -1 0 -394 -1046 +Curve -416 -1042 -437 -1038 +Curve -456 -1034 -475 -1030 +Curve -530 -1015 -585 -1000 +Curve -601 -994 -616 -988 +<-------EndPath +Path 0 0 0 -616 -988 +Curve -621 -957 -625 -925 +Curve -637 -897 -635 -908 +<-------EndPath +Path -1 -1 0 -234 -1074 +Curve -355 -1181 -394 -1046 +<-------EndPath +Path -1 0 0 -394 -1046 +Curve -357 -1053 -320 -1060 +Curve -277 -1067 -234 -1074 +<-------EndPath +Path 0 0 0 -394 -1046 +Curve -399 -1024 -404 -1002 +<-------EndPath +Path 1 0 -1 -404 -1002 +Curve -582 -969 -694 -841 +Curve -718 -814 -729 -781 +Curve -732 -767 -735 -752 +Curve -735 -738 -734 -723 +Curve -731 -708 -728 -692 +Curve -720 -668 -706 -649 +Curve -685 -624 -656 -606 +Curve -496 -520 -319 -464 +Curve -214 -432 -106 -411 +Curve -78 -339 -49 -266 +<-------EndPath +Path 1 1 0 -49 -266 +Curve -48 -265 -47 -263 +Curve -45 -255 -42 -247 +<-------EndPath +Path -1 0 0 -80 -300 +Curve -107 -322 -154 -347 +Curve -287 -417 -454 -453 +Curve -617 -489 -733 -589 +Curve -875 -712 -781 -858 +Curve -873 -974 -747 -901 +Curve -689 -957 -616 -988 +<-------EndPath +Path -1 -1 0 -616 -988 +Curve -581 -1156 -475 -1030 +<-------EndPath +Path 0 0 0 -781 -858 +Curve -764 -880 -747 -901 +<-------EndPath +Path 0 8 0 -80 -282 +Curve -82 -277 -84 -272 +Curve -86 -268 -88 -263 +<-------EndPath +Path 0 2 0 -88 -263 +Curve -101 -244 -113 -224 +Curve -115 -224 -116 -224 +<-------EndPath +Path 0 2 -1 -116 -224 +Curve -119 -224 -121 -224 +<-------EndPath +Path 0 2 0 -121 -224 +Curve -137 -183 -162 -146 +<-------EndPath +Path 6 8 0 -98 -293 +Curve -89 -288 -80 -282 +<-------EndPath +Path 6 0 0 -80 -282 +Curve -77 -289 -74 -295 +Curve -77 -298 -80 -300 +<-------EndPath +Path 6 -1 0 -80 -300 +Curve -89 -297 -98 -293 +<-------EndPath +Path 8 -1 0 -98 -293 +Curve -107 -294 -113 -286 +Curve -122 -275 -126 -245 +<-------EndPath +Path 8 2 0 -126 -245 +Curve -107 -254 -88 -263 +<-------EndPath +Path 0 1 -1 -135 -103 +Curve -133 -104 -131 -105 +Curve -117 -119 -103 -133 +Curve -76 -166 -68 -207 +Curve -65 -206 -62 -205 +Curve -60 -215 -57 -224 +Curve -57 -226 -56 -227 +Curve -55 -233 -54 -238 +Curve -52 -251 -50 -263 +Curve -50 -265 -49 -266 +<-------EndPath +Path 0 0 0 -49 -266 +Curve -62 -281 -74 -295 +<-------EndPath +Path -1 -1 0 -223 -128 +Curve -223 -128 -223 -127 +<-------EndPath +Path -1 7 0 -223 -127 +Curve -223 -128 -222 -128 +<-------EndPath +Path -1 2 -1 -222 -128 +Curve -223 -128 -223 -128 +<-------EndPath +Path -1 2 0 -223 -128 +Curve -200 -203 -126 -245 +<-------EndPath +Path 7 -1 0 -231 -72 +Curve -237 -75 -242 -78 +Curve -245 -85 -248 -92 +Curve -245 -99 -242 -105 +Curve -236 -108 -229 -111 +Curve -221 -111 -215 -105 +Curve -212 -99 -209 -92 +<-------EndPath +Path 7 4 0 -209 -92 +Curve -198 -103 -187 -114 +<-------EndPath +Path 4 7 0 -231 -72 +Curve -237 -68 -242 -64 +Curve -269 -44 -284 -8 +<-------EndPath +Path 4 3 0 -284 -8 +Curve -282 -7 -280 -5 +Curve -199 55 -257 137 +Curve -271 153 -284 169 +Curve -306 193 -329 205 +<-------EndPath +Path 4 -1 0 -329 205 +Curve -332 251 -334 297 +Curve -336 371 -338 444 +<-------EndPath +Path 4 1 0 -338 444 +Curve -327 448 -316 452 +<-------EndPath +Path 4 9 0 -316 452 +Curve -296 460 -275 467 +Curve -165 502 -43 521 +<-------EndPath +Path 4 0 -1 -43 521 +Curve -42 522 -40 522 +<-------EndPath +Path 4 9 0 -40 522 +Curve -33 523 -25 524 +Curve 16 529 56 533 +<-------EndPath +Path 4 4 0 56 533 +Curve 58 513 48 502 +Curve 21 466 39 415 +Curve 40 414 40 412 +Curve 45 392 49 372 +Curve 50 368 50 363 +Curve 50 363 50 362 +Curve 50 361 50 359 +Curve 49 342 48 325 +Curve 48 325 48 324 +Curve 42 286 19 247 +Curve 7 226 2 203 +Curve 1 182 0 161 +Curve 3 114 6 66 +<-------EndPath +Path 4 -1 0 -209 -92 +Curve -220 -82 -231 -72 +<-------EndPath +Path 2 7 0 -222 -128 +Curve -194 -142 -171 -135 +<-------EndPath +Path 3 7 0 -284 -8 +Curve -287 -1 -289 6 +Curve -291 13 -293 19 +<-------EndPath +Path 3 -1 0 -293 19 +Curve -299 39 -304 59 +<-------EndPath +Path 3 3 0 -304 59 +Curve -295 54 -285 49 +<-------EndPath +Path 3 -1 0 -304 59 +Curve -322 131 -329 205 +<-------EndPath +Path 1 -1 0 -338 444 +Curve -339 457 -340 470 +<-------EndPath +Path 1 9 -1 -340 470 +Curve -328 461 -316 452 +<-------EndPath +Path -1 -1 0 -340 547 +Curve -386 511 -410 444 +Curve -447 341 -420 221 +Curve -397 115 -304 59 +<-------EndPath +Path 0 9 -1 -43 521 +Curve -43 522 -43 522 +Curve -42 522 -40 522 +<-------EndPath +Path 9 9 0 -2 595 +Curve -32 629 -78 626 +Curve -42 651 -14 658 +<-------EndPath +Path 9 9 0 -26 583 +Curve -53 605 -79 626 +Curve -79 626 -78 626 +<-------EndPath +Path 9 9 0 -340 547 +Curve -306 573 -259 582 +Curve -177 597 -124 616 +Curve -102 621 -79 626 +<-------EndPath +Path 9 -1 0 -340 547 +Curve -343 562 -345 576 +Curve -347 600 -349 624 +Curve -350 654 -351 683 +<-------EndPath +Path 9 10 0 -351 683 +Curve -283 731 -208 766 +Curve -142 797 -71 817 +Curve -69 818 -67 818 +Curve -47 823 -26 828 +Curve 47 836 119 844 +Curve 153 847 186 850 +Curve 217 849 247 847 +Curve 413 836 537 773 +Curve 583 749 612 715 +<-------EndPath +Path 9 -1 0 612 715 +Curve 616 621 619 527 +Curve 619 445 603 372 +<-------EndPath +Path 9 9 0 603 372 +Curve 602 376 601 379 +Curve 546 471 464 546 +Curve 428 584 392 621 +Curve 392 622 392 622 +Curve 388 663 365 689 +<-------EndPath +Path -1 10 0 -189 1029 +Curve -229 1014 -251 981 +Curve -272 951 -292 921 +Curve -351 829 -351 683 +<-------EndPath +Path 10 10 0 -67 818 +Curve -62 893 -88 934 +Curve -97 922 -119 918 +Curve -246 891 -208 766 +<-------EndPath +Path 9 -1 0 -340 470 +Curve -340 509 -340 547 +<-------EndPath +Path -1 10 -1 -63 1044 +Curve -65 1042 -67 1040 +Curve -107 1035 -146 1029 +Curve -145 1045 -160 1031 +Curve -175 1030 -189 1029 +<-------EndPath +Path -1 -1 0 -189 1029 +Curve -171 1034 -152 1039 +Curve -138 1041 -124 1042 +Curve -94 1043 -63 1044 +<-------EndPath +Path 10 -1 0 -63 1044 +Curve -60 1044 -57 1044 +Curve -22 1044 14 1044 +Curve 84 1041 154 1038 +Curve 189 1036 197 999 +Curve 209 948 238 921 +Curve 258 1056 401 1066 +Curve 402 1066 402 1066 +Curve 445 1065 487 1064 +Curve 507 1059 527 1053 +Curve 568 1035 578 979 +Curve 602 844 612 715 +<-------EndPath +Path 11 -1 -1 -117 1057 +Curve -135 1048 -152 1039 +<-------EndPath +Path 11 -1 0 -152 1039 +Curve -134 1063 -139 1098 +Curve -128 1078 -117 1057 +<-------EndPath +Path 11 -1 -1 -149 1205 +Curve -144 1202 -138 1199 +<-------EndPath +Path 11 -1 0 -138 1199 +Curve -148 1175 -171 1166 +Curve -177 1165 -182 1163 +Curve -257 1148 -328 1174 +Curve -328 1174 -328 1173 +Curve -355 1116 -418 1078 +Curve -481 1041 -554 1027 +Curve -512 1114 -469 1174 +Curve -457 1191 -430 1200 +Curve -357 1225 -279 1227 +Curve -204 1228 -149 1205 +<-------EndPath +Path -1 -1 0 -139 1098 +Curve -155 1132 -171 1166 +<-------EndPath +Path 6 -1 0 721 44 +Curve 718 53 714 61 +Curve 707 68 696 69 +Curve 685 68 678 61 +Curve 671 54 671 44 +Curve 671 33 678 26 +Curve 685 18 696 19 +Curve 707 18 714 26 +Curve 721 33 721 44 +<-------EndPath +Path 6 12 0 616 3 +Curve 631 29 636 70 +Curve 643 134 624 186 +<-------EndPath +Path 6 -1 0 624 186 +Curve 625 187 625 187 +Curve 625 202 614 210 +<-------EndPath +Path 13 -1 0 718 259 +Curve 710 262 701 264 +Curve 724 329 746 393 +Curve 765 379 783 364 +Curve 797 352 820 346 +Curve 814 297 783 233 +Curve 775 237 767 241 +<-------EndPath +Path 13 14 0 767 241 +Curve 776 261 784 280 +Curve 759 287 734 293 +Curve 726 276 718 259 +<-------EndPath +Path -1 14 0 718 259 +Curve 743 250 767 241 +<-------EndPath +Path 6 6 0 725 205 +Curve 719 186 712 167 +<-------EndPath +Path -1 6 0 725 205 +Curve 705 223 674 223 +<-------EndPath +Path 3 6 0 470 107 +Curve 466 102 461 97 +Curve 436 70 410 43 +<-------EndPath +Path 3 4 0 278 -59 +Curve 328 71 416 108 +Curve 442 119 472 122 +Curve 478 123 483 123 +<-------EndPath +Path 1 4 0 599 355 +Curve 599 355 598 355 +<-------EndPath +Path 1 9 -1 598 355 +Curve 599 355 599 355 +<-------EndPath +Path -1 9 0 599 355 +Curve 601 364 603 372 +<-------EndPath +Path -1 -1 0 603 372 +Curve 607 350 611 327 +<-------EndPath +Path -1 5 0 611 327 +Curve 604 336 596 345 +<-------EndPath +Path -1 4 0 596 345 +Curve 598 350 599 355 +<-------EndPath +Path 9 4 0 598 355 +Curve 581 385 556 409 +Curve 499 467 419 499 +Curve 359 522 287 530 +Curve 175 541 56 533 +<-------EndPath +Path 13 14 0 783 328 +Curve 781 333 779 337 +Curve 775 341 770 341 +Curve 765 339 760 337 +Curve 759 333 757 328 +Curve 756 322 760 318 +Curve 764 314 770 315 +Curve 775 317 779 318 +Curve 781 323 783 328 +<-------EndPath +Path 14 14 0 758 259 +Curve 761 266 763 272 +<-------EndPath +Path 4 5 0 596 345 +Curve 577 279 546 219 +<-------EndPath +Path 7 12 0 563 -49 +Curve 586 -17 587 21 +Curve 602 12 616 3 +<-------EndPath +Path 9 9 0 331 666 +Curve 357 652 391 622 +Curve 355 638 310 631 +<-------EndPath +Path 9 9 0 392 621 +Curve 392 622 391 622 +Curve 392 622 392 622 +<-------EndPath +Path 9 9 0 129 696 +Curve 147 677 182 684 +Curve 181 712 153 714 +<-------EndPath +Path 10 0 0 155 849 +Curve 164 850 172 850 +<-------EndPath +Path 10 10 0 172 850 +Curve 179 850 186 850 +<-------EndPath +Path 10 0 -1 144 850 +Curve 131 850 117 849 +Curve 99 847 107 847 +Curve 131 848 155 849 +<-------EndPath +Path 10 0 0 172 850 +Curve 158 850 144 850 +<-------EndPath +Path -1 11 0 99 1231 +Curve 163 1190 242 1177 +Curve 317 1181 391 1184 +Curve 406 1188 416 1194 +Curve 417 1194 417 1194 +Curve 449 1156 493 1137 +Curve 500 1134 506 1131 +<-------EndPath +Path -1 -1 0 506 1131 +Curve 507 1131 507 1131 +Curve 502 1096 487 1064 +<-------EndPath +Path -1 -1 0 507 1131 +Curve 508 1134 508 1136 +<-------EndPath +Path -1 11 0 508 1136 +Curve 509 1152 510 1168 +Curve 510 1176 509 1183 +Curve 497 1236 416 1246 +Curve 339 1255 259 1249 +Curve 182 1246 104 1242 +<-------EndPath +Path -1 11 -1 104 1242 +Curve 102 1237 99 1231 +<-------EndPath +Path -1 11 -1 506 1131 +Curve 507 1134 508 1136 +<-------EndPath +Path 7 -1 0 -223 -127 +Curve -317 -93 -293 19 +<-------EndPath +!======EndShape diff --git a/examples/art/spheres.bmp b/examples/art/spheres.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9889fb899d181162feab9450cd0c87916b3ba765 GIT binary patch literal 288054 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 bmgg3O>wIb}na6M_(t4u34)k^Ge!ckzq))Dl literal 0 HcmV?d00001 diff --git a/examples/art/spheres.ppm b/examples/art/spheres.ppm new file mode 100644 index 0000000000000000000000000000000000000000..1c1086137e78dbbe7d6e7f56493fa9cd1fd2ec3e GIT binary patch literal 288015 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%0A+RqiG%Z3J!?G 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%0Dw%~Bf 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%0AyRW~$ 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 literal 0 HcmV?d00001 diff --git a/examples/art/tiger.svg b/examples/art/tiger.svg new file mode 100644 index 0000000..234c167 --- /dev/null +++ b/examples/art/tiger.svg @@ -0,0 +1,728 @@ + + + +A less cute tiger + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/art/timesi.zip b/examples/art/timesi.zip new file mode 100644 index 0000000000000000000000000000000000000000..10fd933b538d0f5a78a487f85630be83798b7e3c GIT binary patch literal 152912 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

-(S#6U;XS4EPNxl+!? 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

@x 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 literal 0 HcmV?d00001 diff --git a/examples/bezier_div.cpp b/examples/bezier_div.cpp new file mode 100644 index 0000000..feb91e6 --- /dev/null +++ b/examples/bezier_div.cpp @@ -0,0 +1,572 @@ +#include +#include +#include +#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 m_curve1; + agg::slider_ctrl m_angle_tolerance; + agg::slider_ctrl m_approximation_scale; + agg::slider_ctrl m_cusp_limit; + agg::slider_ctrl m_width; + agg::cbox_ctrl m_show_points; + agg::cbox_ctrl m_show_outline; + agg::rbox_ctrl m_curve_type; + agg::rbox_ctrl m_case_type; + agg::rbox_ctrl m_inner_join; + agg::rbox_ctrl m_line_join; + agg::rbox_ctrl m_line_cap; + + int m_cur_case_type; + +public: + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid 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 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 + 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 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 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 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 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 > 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 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 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; +} + + + + + diff --git a/examples/blend_color.cpp b/examples/blend_color.cpp new file mode 100644 index 0000000..9ee957a --- /dev/null +++ b/examples/blend_color.cpp @@ -0,0 +1,555 @@ +#include +#include +#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 m_method; + agg::slider_ctrl m_radius; + agg::polygon_ctrl m_shadow_ctrl; + + agg::path_storage m_path; + typedef agg::conv_curve 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 m_gray8_buf; + agg::rendering_buffer m_gray8_rbuf; + agg::rendering_buffer m_gray8_rbuf2; + + agg::pod_array 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 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 blender_type; + //typedef agg::comp_adaptor_rgba blend_adaptor_type; + //typedef agg::pixfmt_custom_blend_rgba pixfmt_type; + //typedef agg::renderer_base ren_base; + //pixfmt_type pixf_blend(rbuf_window()); + //agg::renderer_base renb_blend(pixf_blend); + + pixfmt pixf(rbuf_window()); + agg::renderer_base 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 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 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; +} + + diff --git a/examples/blur.cpp b/examples/blur.cpp new file mode 100644 index 0000000..ba82904 --- /dev/null +++ b/examples/blur.cpp @@ -0,0 +1,327 @@ +#include +#include +#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 m_method; + agg::slider_ctrl m_radius; + agg::polygon_ctrl m_shadow_ctrl; + agg::cbox_ctrl m_channel_r; + agg::cbox_ctrl m_channel_g; + agg::cbox_ctrl m_channel_b; + + agg::path_storage m_path; + typedef agg::conv_curve 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 > m_stack_blur; + agg::recursive_blur > 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 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 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, + agg::rendering_buffer, + 3, component_order::R> pixfmt_r; + typedef agg::pixfmt_alpha_blend_gray< + agg::blender_gray, + agg::rendering_buffer, + 3, component_order::G> pixfmt_g; + typedef agg::pixfmt_alpha_blend_gray< + agg::blender_gray, + 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 > 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 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; +} + + diff --git a/examples/bspline.cpp b/examples/bspline.cpp new file mode 100644 index 0000000..afccea4 --- /dev/null +++ b/examples/bspline.cpp @@ -0,0 +1,207 @@ +#include +#include +#include +#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 renderer_base; + typedef agg::scanline_p8 scanline_type; + + agg::interactive_polygon m_poly; + agg::slider_ctrl m_num_points; + agg::cbox_ctrl 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 conv_bspline_type; + conv_bspline_type bspline(path); + bspline.interpolation_step(1.0 / m_num_points.value()); + + typedef agg::conv_stroke 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; +} + + + + + + + + + + diff --git a/examples/circles.cpp b/examples/circles.cpp new file mode 100644 index 0000000..4e04ff6 --- /dev/null +++ b/examples/circles.cpp @@ -0,0 +1,268 @@ +#include +#include +#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 m_scale_ctrl_z; + agg::slider_ctrl m_slider_ctrl_sel; + agg::slider_ctrl 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 renderer_base; + + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + + rb.clear(agg::rgba(1,1,1)); + + agg::ellipse e1; + agg::conv_transform 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; +} + + diff --git a/examples/component_rendering.cpp b/examples/component_rendering.cpp new file mode 100644 index 0000000..e45a883 --- /dev/null +++ b/examples/component_rendering.cpp @@ -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_blender; + +enum flip_y_e { flip_y = true }; + + +class the_application : public agg::platform_support +{ + agg::slider_ctrl 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 pixfmt_r; + typedef agg::pixfmt_alpha_blend_gray pixfmt_g; + typedef agg::pixfmt_alpha_blend_gray pixfmt_b; + + pixfmt_r pfr(rbuf_window()); + pixfmt_g pfg(rbuf_window()); + pixfmt_b pfb(rbuf_window()); + + agg::renderer_base rbase(pf); + agg::renderer_base rbr(pfr); + agg::renderer_base rbg(pfg); + agg::renderer_base 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; +} + + diff --git a/examples/compositing.cpp b/examples/compositing.cpp new file mode 100644 index 0000000..bf9b1cf --- /dev/null +++ b/examples/compositing.cpp @@ -0,0 +1,374 @@ +#include +#include +#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 prim_blender_type; +typedef agg::pixfmt_alpha_blend_rgba prim_pixfmt_type; +typedef agg::renderer_base 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 ::blend_pix(p,0,0,0,0,0); + //agg::comp_op_rgba_invert ::blend_pix(p,0,0,0,0,0); + //agg::comp_op_rgba_contrast ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_darken ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_lighten ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_color_dodge::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_color_burn ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_hard_light ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_soft_light ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_difference ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_exclusion ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_src_atop ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_dst_atop ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_xor ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_plus ::blend_pix(p,0,0,0,0,0); + //agg::comp_op_rgba_minus ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_multiply ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_screen ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_overlay ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_src ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_dst ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_src_over ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_dst_over ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_src_in ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_dst_in ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_src_out ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_dst_out ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_clear ::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 +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_func_type; + typedef agg::span_interpolator_linear<> interpolator_type; + typedef agg::span_allocator span_allocator_type; + typedef agg::span_gradient 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 +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_func_type; + typedef agg::span_interpolator_linear<> interpolator_type; + typedef agg::span_allocator span_allocator_type; + typedef agg::span_gradient 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 m_alpha_src; + agg::slider_ctrl m_alpha_dst; + agg::rbox_ctrl 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 blender_type; + typedef agg::pixfmt_custom_blend_rgba pixfmt_type; + typedef agg::renderer_base renderer_type; + + pixfmt_type ren_pixf(rbuf); + renderer_type renderer(ren_pixf); + + agg::renderer_base 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 blender_type_pre; + typedef agg::pixfmt_alpha_blend_rgba pixfmt_pre; + typedef agg::renderer_base 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 ren(rb); + + char buf[64]; + agg::gsv_text t; + t.size(10.0); + + agg::conv_stroke 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; +} + + diff --git a/examples/compositing2.cpp b/examples/compositing2.cpp new file mode 100644 index 0000000..7d8a7ed --- /dev/null +++ b/examples/compositing2.cpp @@ -0,0 +1,251 @@ +#include +#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 prim_blender_type; +typedef agg::pixfmt_alpha_blend_rgba prim_pixfmt_type; +typedef agg::renderer_base 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 ::blend_pix(p,0,0,0,0,0); + //agg::comp_op_rgba_invert ::blend_pix(p,0,0,0,0,0); + //agg::comp_op_rgba_contrast ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_darken ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_lighten ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_color_dodge::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_color_burn ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_hard_light ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_soft_light ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_difference ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_exclusion ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_src_atop ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_dst_atop ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_xor ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_plus ::blend_pix(p,0,0,0,0,0); + //agg::comp_op_rgba_minus ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_multiply ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_screen ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_overlay ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_src ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_dst ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_src_over ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_dst_over ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_src_in ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_dst_in ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_src_out ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_dst_out ::blend_pix(p,0,0,0,0,0); + agg::comp_op_rgba_clear ::blend_pix(p,0,0,0,0,0); +} + + +template +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 m_alpha_dst; + agg::slider_ctrl m_alpha_src; + agg::rbox_ctrl m_comp_op; + + agg::pod_auto_array m_ramp1; + agg::pod_auto_array 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 + 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 span_allocator_type; + typedef agg::span_gradient 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 trans(ell, trans_affine_resizing()); + m_ras.add_path(trans); + + agg::render_scanlines_aa(m_ras, m_sl, rbase, span_allocator, span_gradient); + } + + + template void render_scene(RenBase& rb) + { + typedef agg::comp_op_adaptor_rgba blender_type; + typedef agg::pixfmt_custom_blend_rgba pixfmt_type; + typedef agg::renderer_base 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 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; +} + + diff --git a/examples/conv_contour.cpp b/examples/conv_contour.cpp new file mode 100644 index 0000000..c37382d --- /dev/null +++ b/examples/conv_contour.cpp @@ -0,0 +1,164 @@ +#include +#include +#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 m_close; + agg::slider_ctrl m_width; + agg::cbox_ctrl 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 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 trans(m_path, mtx); + agg::conv_curve > curve(trans); + + agg::conv_contour + > > 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; +} + + diff --git a/examples/conv_dash_marker.cpp b/examples/conv_dash_marker.cpp new file mode 100644 index 0000000..0a34d57 --- /dev/null +++ b/examples/conv_dash_marker.cpp @@ -0,0 +1,286 @@ +#include +#include +#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 m_cap; + agg::slider_ctrl m_width; + agg::slider_ctrl m_smooth; + agg::cbox_ctrl m_close; + agg::cbox_ctrl 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 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 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 > 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 > curve(smooth); + agg::conv_dash >, agg::vcgen_markers_term> dash(curve); + agg::conv_stroke >, 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 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; +} + + diff --git a/examples/conv_stroke.cpp b/examples/conv_stroke.cpp new file mode 100644 index 0000000..9ebdfc8 --- /dev/null +++ b/examples/conv_stroke.cpp @@ -0,0 +1,276 @@ +#include +#include +#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 m_join; + agg::rbox_ctrl m_cap; + agg::slider_ctrl m_width; + agg::slider_ctrl 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 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 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 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 > poly2_dash(stroke); + agg::conv_stroke > > 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; +} + + diff --git a/examples/distortions.cpp b/examples/distortions.cpp new file mode 100644 index 0000000..4c4f7a3 --- /dev/null +++ b/examples/distortions.cpp @@ -0,0 +1,709 @@ +#include +#include +#include +#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 m_angle; + agg::slider_ctrl m_scale; + agg::slider_ctrl m_amplitude; + agg::slider_ctrl m_period; + agg::rbox_ctrl m_distortion; + + double m_center_x; + double m_center_y; + double m_phase; + + typedef agg::pod_auto_array 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 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 span_alloc_type; + + span_alloc_type sa; + + typedef agg::span_interpolator_adaptor, + 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 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 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 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 span_gen_type; + agg::image_filter filter; + span_gen_type sg(img_src, interpolator, filter); + //------------------------------------------ +*/ +/* + // Version with arbitrary filter + //------------------------------------------ + typedef agg::span_image_filter_rgb span_gen_type; + agg::image_filter 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 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 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 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; +} + + diff --git a/examples/flash_rasterizer.cpp b/examples/flash_rasterizer.cpp new file mode 100644 index 0000000..4feef6a --- /dev/null +++ b/examples/flash_rasterizer.cpp @@ -0,0 +1,561 @@ +#include +#include +#include +#include +#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 m_curve; + conv_transform > m_trans; + pod_bvector 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 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 renderer_base; + typedef agg::renderer_scanline_aa_solid 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 ras; + agg::rasterizer_compound_aa rasc; + agg::scanline_u8 sl; + agg::scanline_bin sl_bin; + agg::conv_transform shape(m_shape, m_scale); + agg::conv_stroke > stroke(shape); + + agg::test_styles style_handler(m_colors, m_gradient.data()); + agg::span_allocator 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 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; +} + + + + + diff --git a/examples/flash_rasterizer2.cpp b/examples/flash_rasterizer2.cpp new file mode 100644 index 0000000..ad734ff --- /dev/null +++ b/examples/flash_rasterizer2.cpp @@ -0,0 +1,535 @@ +#include +#include +#include +#include +#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::max()), + m_max_style(std::numeric_limits::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::max(); + m_max_style = std::numeric_limits::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 m_curve; + conv_transform > m_trans; + pod_bvector 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 renderer_base; + typedef agg::renderer_scanline_aa_solid 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 ras; + agg::scanline_u8 sl; + agg::conv_transform shape(m_shape, m_scale); + agg::conv_stroke > 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 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; +} + + + + + diff --git a/examples/freetype_test.cpp b/examples/freetype_test.cpp new file mode 100644 index 0000000..ea67bed --- /dev/null +++ b/examples/freetype_test.cpp @@ -0,0 +1,484 @@ +#include +#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 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 base_ren_type; + typedef agg::renderer_scanline_aa_solid renderer_solid; + typedef agg::renderer_scanline_bin_solid renderer_bin; + typedef agg::font_engine_freetype_int32 font_engine_type; + typedef agg::font_cache_manager font_manager_type; + + agg::rbox_ctrl m_ren_type; + agg::slider_ctrl m_height; + agg::slider_ctrl m_width; + agg::slider_ctrl m_weight; + agg::slider_ctrl m_gamma; + agg::cbox_ctrl m_hinting; + agg::cbox_ctrl m_kerning; + agg::cbox_ctrl 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 m_curves; + agg::conv_contour > 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 + 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; +} + + diff --git a/examples/gamma_correction.cpp b/examples/gamma_correction.cpp new file mode 100644 index 0000000..aea5762 --- /dev/null +++ b/examples/gamma_correction.cpp @@ -0,0 +1,178 @@ +#include +#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 m_thickness; + agg::slider_ctrl m_contrast; + agg::slider_ctrl 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 gamma_type; + typedef pixfmt_gamma pixfmt_type; + typedef agg::renderer_base ren_base; + + double g = m_gamma.value(); + gamma_type gamma(g); + pixfmt_type pixf(rbuf_window(), gamma); +#else + typedef agg::renderer_base 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 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 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; +} + + diff --git a/examples/gamma_ctrl.cpp b/examples/gamma_ctrl.cpp new file mode 100644 index 0000000..c2a3432 --- /dev/null +++ b/examples/gamma_ctrl.cpp @@ -0,0 +1,251 @@ +#include +#include +#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 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 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 poly(ellipse); + agg::conv_transform > 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 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 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; +} + + diff --git a/examples/gamma_tuner.cpp b/examples/gamma_tuner.cpp new file mode 100644 index 0000000..c5cb05b --- /dev/null +++ b/examples/gamma_tuner.cpp @@ -0,0 +1,236 @@ +#include +#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 m_gamma; + agg::slider_ctrl m_r; + agg::slider_ctrl m_g; + agg::slider_ctrl m_b; + agg::rbox_ctrl 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 gamma_type; + + typedef pixfmt_gamma pixfmt_type; + typedef agg::renderer_base 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; +} + + diff --git a/examples/gouraud.cpp b/examples/gouraud.cpp new file mode 100644 index 0000000..c6840d2 --- /dev/null +++ b/examples/gouraud.cpp @@ -0,0 +1,314 @@ +#include +#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 m_dilation; + agg::slider_ctrl m_gamma; + agg::slider_ctrl 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 + void render_gouraud(Scanline& sl, Ras& ras) + { + double alpha = m_alpha.value(); + double brc = 1; + + typedef agg::renderer_base base_ren_type; +#ifdef AGG_GRAY8 + typedef agg::span_gouraud_gray span_gen_type; +#else + typedef agg::span_gouraud_rgba span_gen_type; +#endif + typedef agg::span_allocator 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 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; +} + + diff --git a/examples/gouraud_mesh.cpp b/examples/gouraud_mesh.cpp new file mode 100644 index 0000000..5d78c26 --- /dev/null +++ b/examples/gouraud_mesh.cpp @@ -0,0 +1,485 @@ +#include +#include +#include +#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 m_vertices; + pod_bvector m_triangles; + pod_bvector 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 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 m_triangles; + }; +} + + + + + +class the_application : public agg::platform_support +{ + +public: + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid 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 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 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; +} + + + + + diff --git a/examples/gpc_test.cpp b/examples/gpc_test.cpp new file mode 100644 index 0000000..343670b --- /dev/null +++ b/examples/gpc_test.cpp @@ -0,0 +1,685 @@ +#include +#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 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 m_polygons; + agg::rbox_ctrl 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 + 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 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 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 + unsigned render_gpc(Scanline& sl, Ras& ras) + { + pixfmt pf(rbuf_window()); + agg::renderer_base rb(pf); + agg::renderer_scanline_aa_solid > ren(rb); + + + switch(m_polygons.cur_item()) + { + case 0: + { + //------------------------------------ + // Two simple paths + // + agg::path_storage ps1; + agg::path_storage ps2; + + agg::conv_gpc 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 stroke(ps2); + stroke.width(10.0); + + agg::conv_gpc > 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 trans_gb_poly(gb_poly, mtx1); + agg::conv_transform trans_arrows(arrows, mtx2); + + agg::conv_gpc, + agg::conv_transform > 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 > 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 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 trans_gb_poly(gb_poly, mtx); + + agg::conv_gpc, + agg::conv_stroke > 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 > 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 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 trans(glyph, mtx); + agg::conv_curve > curve(trans); + + agg::conv_gpc, + 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 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 base_ren_type; + typedef agg::renderer_scanline_aa_solid 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 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; +} + + diff --git a/examples/gradient_focal.cpp b/examples/gradient_focal.cpp new file mode 100644 index 0000000..255b0bb --- /dev/null +++ b/examples/gradient_focal.cpp @@ -0,0 +1,252 @@ +#include +#include +#include +#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 renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_solid; + typedef agg::gamma_lut gamma_lut_type; + typedef agg::gradient_radial_focus gradient_func_type; + typedef agg::gradient_reflect_adaptor gradient_adaptor_type; + typedef agg::gradient_lut, 1024> color_func_type; + typedef agg::span_interpolator_linear<> interpolator_type; + typedef agg::span_allocator span_allocator_type; + typedef agg::span_gradient span_gradient_type; + + agg::slider_ctrl 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 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 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; +} + + diff --git a/examples/gradients.cpp b/examples/gradients.cpp new file mode 100644 index 0000000..717170b --- /dev/null +++ b/examples/gradients.cpp @@ -0,0 +1,531 @@ +#include +#include +#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 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 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 m_profile; + agg::spline_ctrl m_spline_r; + agg::spline_ctrl m_spline_g; + agg::spline_ctrl m_spline_b; + agg::spline_ctrl m_spline_a; + agg::rbox_ctrl 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 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 t1(e1, mtx1); + + gradient_polymorphic_wrapper gr_circle; + gradient_polymorphic_wrapper gr_diamond; + gradient_polymorphic_wrapper gr_x; + gradient_polymorphic_wrapper gr_xy; + gradient_polymorphic_wrapper gr_sqrt_xy; + gradient_polymorphic_wrapper 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 gradient_span_gen; + typedef agg::span_allocator 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; +} + + diff --git a/examples/gradients_contour.cpp b/examples/gradients_contour.cpp new file mode 100644 index 0000000..4353677 --- /dev/null +++ b/examples/gradients_contour.cpp @@ -0,0 +1,1797 @@ +//---------------------------------------------------------------------------- +// 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 +// +// 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. +// +// [History] ----------------------------------------------------------------- +// +// 03.02.2008-Milano: Ported from Object Pascal code of AggPas +// +#include + +#include "agg_span_gradient_image.h" +#include "agg_span_gradient_contour.h" + +#include "agg_basics.h" +#include "agg_array.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_span_gradient.h" +#include "agg_span_interpolator_linear.h" +#include "agg_span_interpolator_trans.h" +#include "agg_alpha_mask_u8.h" +#include "agg_path_storage.h" +#include "agg_gradient_lut.h" +#include "agg_bounding_rect.h" +#include "agg_trans_perspective.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" +#include "ctrl/agg_polygon_ctrl.h" + +#define AGG_BGR24 +#include "pixel_formats.h" + +enum flip_y_e { flip_y = true }; + +const double angle = 10; +const double zoom_up = 1.1; +const double zoom_down = 0.9; + +//==========================================================gradient_conic +class gradient_conic_angle +{ +public: + static AGG_INLINE int calculate(int x, int y, int d) + { + double res = atan2(double(y), double(x)); + + if (res < 0) + { + return abs(1600 - agg::uround(fabs(res) * double(d) / agg::pi / 2 ) ); + } + else; + { + return agg::uround(res * double(d) / agg::pi / 2 ); + } + + } +}; + +//==========================================================spiral +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 +{ + +const int8u puzzle[] = +{ + 0x02,0x51,0xAE,0xFF,0x00,0x5C,0xB0,0xFF,0x0A,0x85,0xFF,0xFF,0x3B,0x87,0x95,0xFF,0x28,0x27,0x12,0xFF, + 0x5C,0x6F,0x03,0xFF,0x88,0xAD,0x08,0xFF,0x90,0xAC,0x00,0xFF,0x8E,0xAC,0x00,0xFF,0x8B,0xAE,0x00,0xFF, + 0x8C,0xAD,0x00,0xFF,0x9E,0xBE,0x05,0xFF,0xA5,0xC7,0x2B,0xFF,0x5A,0x89,0x67,0xFF,0x17,0x45,0x52,0xFF, + 0x00,0x36,0x80,0xFF,0x03,0x53,0xAA,0xFF,0x00,0x54,0xA4,0xFF,0x00,0x52,0xB1,0xFF,0x04,0x55,0xB1,0xFF, + 0x00,0x50,0xAC,0xFF,0x00,0x52,0xA9,0xFF,0x00,0x4F,0x98,0xFF,0x00,0x43,0x84,0xFF,0x00,0x48,0x9C,0xFF, + 0x06,0x55,0xA4,0xFF,0x03,0x4F,0xA5,0xFF,0x01,0x50,0xAC,0xFF,0x00,0x54,0xAE,0xFF,0x05,0x4E,0xAD,0xFF, + 0x01,0x54,0xBA,0xFF,0x00,0x51,0xAC,0xFF,0x00,0x51,0xAC,0xFF,0x03,0x52,0xAF,0xFF,0x00,0x50,0xB1,0xFF, + 0x03,0x4F,0xAF,0xFF,0x04,0x4F,0xAA,0xFF,0x00,0x56,0xA7,0xFF,0x00,0x55,0xAE,0xFF,0x05,0x4E,0xB5,0xFF, + 0x00,0x53,0xA9,0xFF,0x00,0x52,0xA4,0xFF,0x00,0x51,0xAF,0xFF,0x01,0x53,0xA7,0xFF,0x01,0x53,0xA9,0xFF, + 0x04,0x51,0xAB,0xFF,0x03,0x58,0xB2,0xFF,0x00,0x74,0xF6,0xFF,0x14,0x79,0xD1,0xFF,0x34,0x49,0x22,0xFF, + 0x5D,0x75,0x00,0xFF,0x8A,0xB0,0x01,0xFF,0x8F,0xA4,0x00,0xFF,0x8E,0xB0,0x02,0xFF,0x8B,0xAC,0x07,0xFF, + 0x8D,0xAC,0x00,0xFF,0xC0,0xD9,0x04,0xFF,0x91,0xCF,0x2E,0xFF,0x11,0x39,0x43,0xFF,0x00,0x28,0x58,0xFF, + 0x00,0x4C,0x99,0xFF,0x00,0x54,0xAA,0xFF,0x00,0x50,0xA9,0xFF,0x03,0x53,0xAA,0xFF,0x05,0x52,0xAE,0xFF, + 0x00,0x59,0xB0,0xFF,0x00,0x72,0xEE,0xFF,0x35,0x76,0x92,0xFF,0x2C,0x2C,0x12,0xFF,0x64,0x7A,0x00,0xFF, + 0x89,0xB0,0x00,0xFF,0x88,0xAE,0x00,0xFF,0x91,0xAD,0x00,0xFF,0x84,0xAD,0x06,0xFF,0x8F,0xAE,0x0A,0xFF, + 0x9D,0xBB,0x00,0xFF,0xBE,0xF0,0x13,0xFF,0x57,0x8D,0x76,0xFF,0x08,0x2E,0x41,0xFF,0x01,0x44,0x8A,0xFF, + 0x00,0x52,0xA8,0xFF,0x01,0x4F,0xB3,0xFF,0x05,0x4D,0x95,0xFF,0x00,0x40,0x7E,0xFF,0x04,0x3F,0x8F,0xFF, + 0x0C,0x41,0x8F,0xFF,0x00,0x20,0x3E,0xFF,0x00,0x07,0x12,0xFF,0x08,0x23,0x4E,0xFF,0x00,0x3D,0x8C,0xFF, + 0x00,0x58,0xA8,0xFF,0x03,0x56,0xA6,0xFF,0x04,0x50,0xB0,0xFF,0x03,0x51,0xA6,0xFF,0x04,0x51,0xAB,0xFF, + 0x00,0x53,0xA6,0xFF,0x00,0x52,0xAC,0xFF,0x04,0x56,0xA2,0xFF,0x04,0x55,0xAE,0xFF,0x02,0x53,0xAE,0xFF, + 0x00,0x50,0xAC,0xFF,0x00,0x53,0xA6,0xFF,0x06,0x50,0xA7,0xFF,0x06,0x50,0xA5,0xFF,0x01,0x52,0xAE,0xFF, + 0x01,0x55,0xB5,0xFF,0x00,0x55,0xB1,0xFF,0x02,0x4F,0xAB,0xFF,0x07,0x52,0xB7,0xFF,0x00,0x4F,0xAC,0xFF, + 0x00,0x51,0xA5,0xFF,0x01,0x6D,0xD0,0xFF,0x01,0x72,0xD8,0xFF,0x2B,0x45,0x20,0xFF,0x3E,0x4C,0x00,0xFF, + 0x82,0xA6,0x08,0xFF,0x8E,0xAA,0x00,0xFF,0x8B,0xAD,0x01,0xFF,0x8C,0xAD,0x00,0xFF,0x8D,0xAE,0x00,0xFF, + 0xA3,0xCD,0x00,0xFF,0xB6,0xF7,0x17,0xFF,0x34,0x6C,0x6B,0xFF,0x01,0x16,0x2B,0xFF,0x04,0x31,0x6C,0xFF, + 0x00,0x47,0x9B,0xFF,0x00,0x58,0xA9,0xFF,0x06,0x50,0xA9,0xFF,0x00,0x45,0x87,0xFF,0x00,0x4D,0x98,0xFF, + 0x03,0x56,0xB2,0xFF,0x31,0x60,0x6A,0xFF,0x44,0x55,0x0F,0xFF,0x70,0x97,0x00,0xFF,0x8B,0xB1,0x00,0xFF, + 0x8D,0xAA,0x02,0xFF,0x8E,0xAB,0x03,0xFF,0x8D,0xAD,0x02,0xFF,0x89,0xAB,0x0C,0xFF,0x93,0xBA,0x09,0xFF, + 0xC2,0xEB,0x37,0xFF,0x3B,0x77,0x91,0xFF,0x05,0x3A,0x6E,0xFF,0x00,0x4F,0x99,0xFF,0x00,0x53,0xA7,0xFF, + 0x00,0x51,0xA0,0xFF,0x07,0x37,0x83,0xFF,0x0C,0x26,0x41,0xFF,0x00,0x21,0x46,0xFF,0x16,0x56,0x71,0xFF, + 0x32,0x6B,0x65,0xFF,0x14,0x27,0x2D,0xFF,0x00,0x08,0x02,0xFF,0x00,0x1B,0x29,0xFF,0x00,0x38,0x82,0xFF, + 0x00,0x50,0xA8,0xFF,0x01,0x55,0xAB,0xFF,0x07,0x53,0xB3,0xFF,0x00,0x51,0xA3,0xFF,0x06,0x52,0xB4,0xFF, + 0x00,0x58,0xA8,0xFF,0x00,0x4F,0xAB,0xFF,0x00,0x4D,0xB9,0xFF,0x07,0x51,0xB2,0xFF,0x06,0x52,0xAA,0xFF, + 0x03,0x50,0xB8,0xFF,0x09,0x49,0xA0,0xFF,0x00,0x3C,0x7B,0xFF,0x00,0x2F,0x62,0xFF,0x02,0x27,0x5E,0xFF, + 0x04,0x30,0x5D,0xFF,0x00,0x38,0x74,0xFF,0x00,0x48,0x9D,0xFF,0x04,0x56,0xAC,0xFF,0x02,0x51,0xAE,0xFF, + 0x06,0x67,0xD0,0xFF,0x00,0x67,0xE5,0xFF,0x40,0x5C,0x45,0xFF,0x49,0x54,0x06,0xFF,0x78,0x9D,0x00,0xFF, + 0x8E,0xB0,0x00,0xFF,0x8B,0xAB,0x00,0xFF,0x8B,0xA9,0x00,0xFF,0x8E,0xAD,0x09,0xFF,0x93,0xB3,0x0A,0xFF, + 0xCD,0xFD,0x07,0xFF,0xAB,0xE7,0x4B,0xFF,0x29,0x49,0x58,0xFF,0x01,0x0E,0x17,0xFF,0x0A,0x23,0x42,0xFF, + 0x00,0x30,0x69,0xFF,0x00,0x46,0x90,0xFF,0x01,0x12,0x2C,0xFF,0x00,0x24,0x56,0xFF,0x19,0x52,0x70,0xFF, + 0x4A,0x72,0x3E,0xFF,0x74,0x92,0x0C,0xFF,0x84,0xA9,0x00,0xFF,0x8D,0xA9,0x00,0xFF,0x91,0xAC,0x05,0xFF, + 0x8D,0xAE,0x05,0xFF,0x8A,0xA7,0x00,0xFF,0x90,0xB5,0x05,0xFF,0x9C,0xC9,0x0A,0xFF,0xA8,0xC3,0x34,0xFF, + 0x13,0x4B,0x70,0xFF,0x00,0x35,0x5D,0xFF,0x00,0x49,0x92,0xFF,0x02,0x4D,0x9E,0xFF,0x07,0x51,0x98,0xFF, + 0x16,0x57,0x7F,0xFF,0x29,0x59,0x5D,0xFF,0x47,0x6C,0x39,0xFF,0x93,0xBC,0x2F,0xFF,0xD0,0xFF,0x15,0xFF, + 0xCF,0xF7,0x36,0xFF,0x5E,0x85,0x59,0xFF,0x07,0x10,0x1F,0xFF,0x07,0x0A,0x29,0xFF,0x00,0x43,0x84,0xFF, + 0x03,0x56,0xB2,0xFF,0x04,0x49,0xA4,0xFF,0x00,0x55,0xA9,0xFF,0x00,0x55,0xB6,0xFF,0x01,0x50,0xAF,0xFF, + 0x08,0x55,0xAF,0xFF,0x00,0x58,0xA6,0xFF,0x02,0x56,0xAE,0xFF,0x00,0x50,0xAA,0xFF,0x00,0x53,0xB6,0xFF, + 0x0A,0x40,0x6C,0xFF,0x00,0x18,0x2C,0xFF,0x02,0x09,0x0F,0xFF,0x04,0x00,0x02,0xFF,0x04,0x02,0x05,0xFF, + 0x04,0x0B,0x15,0xFF,0x00,0x18,0x37,0xFF,0x03,0x42,0x85,0xFF,0x00,0x55,0xAF,0xFF,0x00,0x6E,0xCE,0xFF, + 0x17,0x68,0xA9,0xFF,0x42,0x5D,0x28,0xFF,0x69,0x7D,0x00,0xFF,0x82,0xA7,0x01,0xFF,0x8B,0xAD,0x00,0xFF, + 0x8A,0xAC,0x00,0xFF,0x90,0xAD,0x05,0xFF,0x8A,0xAC,0x00,0xFF,0x8B,0xAE,0x00,0xFF,0xA3,0xCE,0x00,0xFF, + 0xCF,0xF8,0x30,0xFF,0xAE,0xD0,0x57,0xFF,0x31,0x5F,0x45,0xFF,0x01,0x15,0x2D,0xFF,0x00,0x14,0x1F,0xFF, + 0x03,0x0C,0x2B,0xFF,0x28,0x5E,0x68,0xFF,0x3E,0x78,0x50,0xFF,0x74,0xAA,0x3A,0xFF,0x82,0xA2,0x19,0xFF, + 0x85,0xA5,0x02,0xFF,0x87,0xB0,0x00,0xFF,0x8E,0xAF,0x00,0xFF,0x8B,0xA8,0x02,0xFF,0x8B,0xAE,0x00,0xFF, + 0x8B,0xB0,0x01,0xFF,0x94,0xB8,0x00,0xFF,0xB1,0xD8,0x01,0xFF,0xAA,0xC5,0x2A,0xFF,0x1E,0x46,0x5F,0xFF, + 0x0C,0x2D,0x4C,0xFF,0x07,0x3D,0x85,0xFF,0x16,0x56,0x79,0xFF,0x1B,0x59,0x72,0xFF,0x4B,0x83,0x52,0xFF, + 0x93,0xB9,0x2E,0xFF,0xAD,0xCA,0x10,0xFF,0xA8,0xCB,0x00,0xFF,0xB0,0xD8,0x06,0xFF,0xCD,0xFF,0x03,0xFF, + 0xD1,0xFF,0x11,0xFF,0x7D,0xA2,0x42,0xFF,0x04,0x08,0x14,0xFF,0x00,0x24,0x51,0xFF,0x00,0x53,0xAE,0xFF, + 0x06,0x54,0xA7,0xFF,0x05,0x51,0xB1,0xFF,0x00,0x53,0xA1,0xFF,0x00,0x50,0xAC,0xFF,0x00,0x52,0xB2,0xFF, + 0x00,0x51,0xAB,0xFF,0x03,0x53,0xA8,0xFF,0x01,0x56,0xB0,0xFF,0x0B,0x5A,0x95,0xFF,0x21,0x49,0x48,0xFF, + 0x36,0x4A,0x2F,0xFF,0x5F,0x78,0x25,0xFF,0x6C,0xA2,0x42,0xFF,0x53,0x8F,0x5C,0xFF,0x33,0x4A,0x36,0xFF, + 0x00,0x05,0x00,0xFF,0x00,0x21,0x40,0xFF,0x07,0x43,0x81,0xFF,0x00,0x4B,0x9D,0xFF,0x1A,0x41,0x3E,0xFF, + 0x3D,0x4F,0x05,0xFF,0x7B,0x98,0x00,0xFF,0x89,0xAD,0x05,0xFF,0x8E,0xAA,0x0A,0xFF,0x8B,0xAE,0x00,0xFF, + 0x8D,0xAD,0x04,0xFF,0x8A,0xAB,0x00,0xFF,0x90,0xAE,0x00,0xFF,0x84,0xB6,0x00,0xFF,0xAC,0xD7,0x03,0xFF, + 0xDA,0xFA,0x1D,0xFF,0xB7,0xF7,0x49,0xFF,0x8C,0xBA,0x72,0xFF,0x4D,0x78,0x6F,0xFF,0x3B,0x6D,0x54,0xFF, + 0xD6,0xFF,0x1A,0xFF,0xB4,0xE0,0x11,0xFF,0xA3,0xD0,0x03,0xFF,0x91,0xB4,0x00,0xFF,0x8B,0xAC,0x00,0xFF, + 0x8F,0xAC,0x04,0xFF,0x8D,0xA9,0x00,0xFF,0x8F,0xAE,0x00,0xFF,0x8B,0xAB,0x02,0xFF,0x8B,0xAA,0x06,0xFF, + 0x8D,0xB3,0x00,0xFF,0xA9,0xD4,0x00,0xFF,0xD3,0xFE,0x2A,0xFF,0x72,0xA9,0x43,0xFF,0x05,0x33,0x40,0xFF, + 0x0D,0x40,0x6D,0xFF,0x33,0x74,0x8A,0xFF,0x5B,0x82,0x53,0xFF,0x95,0xB6,0x0F,0xFF,0x9C,0xC4,0x0B,0xFF, + 0x87,0xB7,0x00,0xFF,0x8A,0xB3,0x00,0xFF,0x89,0xA9,0x00,0xFF,0x92,0xB4,0x00,0xFF,0xCE,0xF4,0x03,0xFF, + 0xD0,0xFF,0x17,0xFF,0x0F,0x29,0x28,0xFF,0x05,0x1D,0x39,0xFF,0x00,0x48,0xA0,0xFF,0x00,0x55,0xAD,0xFF, + 0x09,0x50,0xAC,0xFF,0x03,0x52,0xAF,0xFF,0x08,0x53,0xAE,0xFF,0x00,0x52,0xAE,0xFF,0x00,0x4D,0xB5,0xFF, + 0x00,0x5E,0xB2,0xFF,0x11,0x77,0xCB,0xFF,0x33,0x71,0x6E,0xFF,0x57,0x6C,0x0F,0xFF,0x87,0xA5,0x00,0xFF, + 0x9E,0xCF,0x02,0xFF,0xC4,0xF7,0x06,0xFF,0xCA,0xFF,0x0E,0xFF,0xDA,0xFE,0x22,0xFF,0x7C,0x9C,0x31,0xFF, + 0x0E,0x40,0x73,0xFF,0x00,0x3C,0x83,0xFF,0x1A,0x5D,0x65,0xFF,0x4C,0x5B,0x06,0xFF,0x66,0x79,0x05,0xFF, + 0x87,0xA6,0x02,0xFF,0x89,0xAB,0x00,0xFF,0x8F,0xAC,0x04,0xFF,0x8E,0xB0,0x00,0xFF,0x87,0xA9,0x00,0xFF, + 0x8E,0xAD,0x07,0xFF,0x8F,0xAB,0x09,0xFF,0x90,0xAC,0x00,0xFF,0x93,0xAF,0x02,0xFF,0xA8,0xCE,0x00,0xFF, + 0xBF,0xF6,0x07,0xFF,0xCD,0xFF,0x06,0xFF,0xDA,0xFB,0x14,0xFF,0xD2,0xFF,0x20,0xFF,0x99,0xBF,0x00,0xFF, + 0x98,0xB3,0x02,0xFF,0x92,0xAA,0x00,0xFF,0x89,0xA8,0x04,0xFF,0x8D,0xAF,0x00,0xFF,0x8A,0xAF,0x00,0xFF, + 0x89,0xAA,0x03,0xFF,0x90,0xA9,0x07,0xFF,0x8E,0xAF,0x00,0xFF,0x8F,0xA9,0x00,0xFF,0x89,0xAF,0x00,0xFF, + 0x92,0xBB,0x05,0xFF,0xB7,0xE3,0x08,0xFF,0xC0,0xF7,0x28,0xFF,0x76,0xB8,0x7B,0xFF,0x55,0x7F,0x73,0xFF, + 0x8E,0xBA,0x27,0xFF,0x93,0xBF,0x0A,0xFF,0x88,0xA9,0x00,0xFF,0x8D,0xA8,0x01,0xFF,0x8B,0xAA,0x04,0xFF, + 0x89,0xAE,0x00,0xFF,0x90,0xB1,0x0A,0xFF,0x8B,0xA8,0x00,0xFF,0x9C,0xD1,0x00,0xFF,0xCE,0xFB,0x00,0xFF, + 0x3A,0x59,0x4A,0xFF,0x00,0x07,0x00,0xFF,0x04,0x3C,0x79,0xFF,0x01,0x53,0xA9,0xFF,0x00,0x51,0xAB,0xFF, + 0x00,0x54,0xB1,0xFF,0x00,0x4F,0xA9,0xFF,0x01,0x56,0xA7,0xFF,0x04,0x53,0xB2,0xFF,0x00,0x62,0xC8,0xFF, + 0x28,0x7A,0xB4,0xFF,0x47,0x66,0x2D,0xFF,0x6A,0x80,0x04,0xFF,0x81,0xA6,0x00,0xFF,0x8E,0xB0,0x00,0xFF, + 0x9C,0xB0,0x03,0xFF,0x95,0xB9,0x01,0xFF,0xC0,0xEF,0x01,0xFF,0xCD,0xF7,0x00,0xFF,0xB8,0xDF,0x20,0xFF, + 0xAA,0xCE,0x26,0xFF,0x9E,0xC5,0x14,0xFF,0x9D,0xBB,0x01,0xFF,0x8D,0xAC,0x00,0xFF,0x8D,0xAB,0x00,0xFF, + 0x8E,0xAF,0x00,0xFF,0x8B,0xAD,0x00,0xFF,0x8E,0xAC,0x00,0xFF,0x8E,0xAC,0x00,0xFF,0x8D,0xAD,0x00,0xFF, + 0x84,0xAC,0x00,0xFF,0x93,0xB1,0x04,0xFF,0x83,0xB0,0x00,0xFF,0x8D,0xA4,0x00,0xFF,0x85,0xB2,0x00,0xFF, + 0x92,0xB6,0x00,0xFF,0x99,0xC1,0x00,0xFF,0x99,0xBC,0x00,0xFF,0x88,0xAF,0x08,0xFF,0x8E,0xAB,0x01,0xFF, + 0x8E,0xAD,0x00,0xFF,0x8A,0xAE,0x02,0xFF,0x8E,0xAE,0x03,0xFF,0x89,0xA7,0x00,0xFF,0x8D,0xB4,0x01,0xFF, + 0x87,0xAC,0x00,0xFF,0x8C,0xAD,0x00,0xFF,0x89,0xAD,0x05,0xFF,0x8C,0xAD,0x00,0xFF,0x94,0xA8,0x09,0xFF, + 0x96,0xB6,0x00,0xFF,0xBE,0xDA,0x00,0xFF,0xBE,0xFB,0x00,0xFF,0xB5,0xDE,0x00,0xFF,0x97,0xBF,0x00,0xFF, + 0x8E,0xB8,0x00,0xFF,0x89,0xB0,0x00,0xFF,0x8F,0xAE,0x08,0xFF,0x90,0xAB,0x00,0xFF,0x8F,0xAD,0x00,0xFF, + 0x8A,0xAA,0x00,0xFF,0x8C,0xAD,0x04,0xFF,0x99,0xB2,0x00,0xFF,0xCF,0xFF,0x0C,0xFF,0x48,0x78,0x46,0xFF, + 0x02,0x07,0x0B,0xFF,0x00,0x36,0x7F,0xFF,0x07,0x51,0xB0,0xFF,0x00,0x54,0xA9,0xFF,0x03,0x4F,0xAD,0xFF, + 0x01,0x52,0xAD,0xFF,0x05,0x51,0xAF,0xFF,0x00,0x55,0xB1,0xFF,0x02,0x70,0xEB,0xFF,0x38,0x74,0x98,0xFF, + 0x3D,0x48,0x03,0xFF,0x76,0x9C,0x08,0xFF,0x97,0xB7,0x00,0xFF,0x88,0xAE,0x00,0xFF,0x91,0xA8,0x00,0xFF, + 0x8C,0xB1,0x01,0xFF,0x88,0xAF,0x00,0xFF,0x91,0xB4,0x00,0xFF,0xAB,0xD9,0x00,0xFF,0xB0,0xDE,0x00,0xFF, + 0xA5,0xCE,0x06,0xFF,0x8E,0xB7,0x05,0xFF,0x8D,0xAE,0x09,0xFF,0x91,0xAC,0x00,0xFF,0x8A,0xA9,0x03,0xFF, + 0x87,0xAF,0x01,0xFF,0x8E,0xAB,0x01,0xFF,0x8F,0xA8,0x06,0xFF,0x8B,0xAD,0x00,0xFF,0x90,0xAD,0x00,0xFF, + 0x86,0xAC,0x00,0xFF,0x90,0xAC,0x02,0xFF,0x94,0xAC,0x00,0xFF,0x8B,0xAB,0x00,0xFF,0x90,0xAD,0x03,0xFF, + 0x89,0xAB,0x00,0xFF,0x94,0xAB,0x03,0xFF,0x8A,0xB0,0x00,0xFF,0x90,0xAC,0x02,0xFF,0x91,0xAC,0x00,0xFF, + 0x8B,0xA6,0x00,0xFF,0x8E,0xAF,0x00,0xFF,0x8C,0xAF,0x00,0xFF,0x8A,0xAD,0x00,0xFF,0x8A,0xAA,0x07,0xFF, + 0x8D,0xAF,0x00,0xFF,0x8E,0xAB,0x01,0xFF,0x8E,0xAA,0x00,0xFF,0x88,0xAC,0x04,0xFF,0x89,0xAE,0x00,0xFF, + 0x8B,0xAC,0x00,0xFF,0x91,0xAD,0x03,0xFF,0x8B,0xAB,0x00,0xFF,0x83,0xA4,0x00,0xFF,0x86,0xA2,0x02,0xFF, + 0x89,0xA3,0x02,0xFF,0x85,0xA4,0x00,0xFF,0x84,0xA5,0x00,0xFF,0x8D,0xAE,0x00,0xFF,0x8D,0xAA,0x00,0xFF, + 0x8C,0xAC,0x09,0xFF,0x8F,0xB8,0x00,0xFF,0xC2,0xED,0x08,0xFF,0x49,0x63,0x4A,0xFF,0x00,0x1A,0x2D,0xFF, + 0x00,0x44,0x85,0xFF,0x01,0x4D,0xAD,0xFF,0x00,0x55,0xAB,0xFF,0x01,0x52,0xAB,0xFF,0x04,0x4F,0xB5,0xFF, + 0x03,0x51,0xA6,0xFF,0x00,0x5D,0xAA,0xFF,0x0D,0x84,0xFF,0xFF,0x4A,0x79,0x73,0xFF,0x1D,0x29,0x00,0xFF, + 0x6B,0x80,0x07,0xFF,0x8F,0xAF,0x02,0xFF,0x84,0xB1,0x00,0xFF,0x8F,0xAC,0x04,0xFF,0x90,0xAA,0x00,0xFF, + 0x8E,0xAE,0x01,0xFF,0x8A,0xAD,0x00,0xFF,0x8B,0xAC,0x05,0xFF,0x8D,0xB0,0x00,0xFF,0x8A,0xAE,0x00,0xFF, + 0x8A,0xAD,0x00,0xFF,0x8C,0xAD,0x04,0xFF,0x8E,0xAC,0x00,0xFF,0x8A,0xAB,0x04,0xFF,0x8E,0xB1,0x00,0xFF, + 0x8E,0xA8,0x06,0xFF,0x91,0xAD,0x03,0xFF,0x89,0xAB,0x00,0xFF,0x8D,0xA9,0x00,0xFF,0x8F,0xAD,0x00,0xFF, + 0x8D,0xAC,0x08,0xFF,0x8A,0xAB,0x06,0xFF,0x8C,0xAD,0x00,0xFF,0x8D,0xAE,0x00,0xFF,0x8A,0xAA,0x00,0xFF, + 0x8E,0xAD,0x07,0xFF,0x88,0xAE,0x03,0xFF,0x8D,0xAD,0x02,0xFF,0x8B,0xA8,0x02,0xFF,0x8E,0xB0,0x04,0xFF, + 0x8A,0xAF,0x00,0xFF,0x89,0xA6,0x00,0xFF,0x93,0xAC,0x08,0xFF,0x93,0xAB,0x00,0xFF,0x8E,0xAD,0x07,0xFF, + 0x84,0xAA,0x00,0xFF,0x8C,0xB1,0x00,0xFF,0x91,0xAE,0x08,0xFF,0x8F,0xAB,0x00,0xFF,0x83,0xA4,0x0B,0xFF, + 0x7A,0x9C,0x00,0xFF,0x69,0x85,0x00,0xFF,0x52,0x6B,0x03,0xFF,0x47,0x5E,0x04,0xFF,0x54,0x70,0x00,0xFF, + 0x62,0x7E,0x05,0xFF,0x75,0x90,0x03,0xFF,0x8C,0xAD,0x00,0xFF,0x89,0xAA,0x03,0xFF,0x82,0xA9,0x00,0xFF, + 0x90,0xA9,0x0F,0xFF,0x85,0xA6,0x0F,0xFF,0x25,0x47,0x49,0xFF,0x00,0x29,0x5D,0xFF,0x03,0x4C,0x99,0xFF, + 0x04,0x51,0xAD,0xFF,0x01,0x55,0xAB,0xFF,0x04,0x4F,0xB4,0xFF,0x00,0x56,0xB0,0xFF,0x03,0x4F,0xA7,0xFF, + 0x04,0x5A,0xBD,0xFF,0x08,0x7F,0xFF,0xFF,0x46,0x7E,0x71,0xFF,0x1B,0x19,0x04,0xFF,0x5D,0x7C,0x00,0xFF, + 0x8A,0xAB,0x00,0xFF,0x8E,0xAC,0x00,0xFF,0x8B,0xAA,0x04,0xFF,0x8C,0xB2,0x00,0xFF,0x86,0xAA,0x00,0xFF, + 0x8B,0xAC,0x05,0xFF,0x8C,0xAD,0x06,0xFF,0x8E,0xAD,0x00,0xFF,0x93,0xA8,0x0D,0xFF,0x8A,0xAF,0x07,0xFF, + 0x85,0xAC,0x00,0xFF,0x8C,0xAD,0x00,0xFF,0x91,0xB0,0x00,0xFF,0x89,0xAA,0x00,0xFF,0x8A,0xAD,0x00,0xFF, + 0x89,0xAB,0x00,0xFF,0x8F,0xB0,0x01,0xFF,0x8C,0xAC,0x00,0xFF,0x8E,0xAC,0x00,0xFF,0x8E,0xAB,0x03,0xFF, + 0x8B,0xAB,0x00,0xFF,0x93,0xAE,0x01,0xFF,0x8B,0xA8,0x02,0xFF,0x8D,0xB0,0x00,0xFF,0x8A,0xAB,0x00,0xFF, + 0x8B,0xAB,0x00,0xFF,0x88,0xAA,0x00,0xFF,0x90,0xB1,0x00,0xFF,0x8F,0xA8,0x02,0xFF,0x89,0xAA,0x00,0xFF, + 0x8A,0xB5,0x06,0xFF,0x87,0xB1,0x00,0xFF,0x8C,0xAB,0x00,0xFF,0x93,0xA9,0x00,0xFF,0x8C,0xA9,0x00,0xFF, + 0x8C,0xAB,0x05,0xFF,0x8A,0xA8,0x00,0xFF,0x86,0xA9,0x00,0xFF,0x71,0x93,0x01,0xFF,0x5F,0x7E,0x00,0xFF, + 0x3D,0x49,0x0B,0xFF,0x35,0x40,0x16,0xFF,0x3F,0x57,0x0B,0xFF,0x37,0x4D,0x0D,0xFF,0x1C,0x28,0x00,0xFF, + 0x3C,0x48,0x0A,0xFF,0x56,0x68,0x04,0xFF,0x64,0x7C,0x04,0xFF,0x52,0x6B,0x10,0xFF,0x57,0x7E,0x2F,0xFF, + 0x46,0x71,0x43,0xFF,0x1D,0x55,0x70,0xFF,0x08,0x46,0x93,0xFF,0x01,0x4F,0xA1,0xFF,0x05,0x53,0xA5,0xFF, + 0x03,0x56,0xA4,0xFF,0x00,0x4D,0xAC,0xFF,0x02,0x4D,0xB2,0xFF,0x00,0x54,0xAB,0xFF,0x03,0x59,0xB0,0xFF, + 0x05,0x85,0xFF,0xFF,0x44,0x8B,0x79,0xFF,0x01,0x12,0x00,0xFF,0x53,0x6D,0x00,0xFF,0x88,0xA3,0x00,0xFF, + 0x93,0xA9,0x06,0xFF,0x8E,0xAC,0x00,0xFF,0x8D,0xAB,0x00,0xFF,0x90,0xAC,0x00,0xFF,0x90,0xAC,0x09,0xFF, + 0x89,0xB1,0x01,0xFF,0x73,0x98,0x00,0xFF,0x75,0x95,0x03,0xFF,0x7F,0x99,0x00,0xFF,0x85,0xA3,0x05,0xFF, + 0x8B,0xAF,0x07,0xFF,0x93,0xB2,0x00,0xFF,0x8D,0xA9,0x06,0xFF,0x8B,0xB2,0x01,0xFF,0x89,0xAE,0x00,0xFF, + 0x8D,0xAA,0x00,0xFF,0x83,0xB3,0x00,0xFF,0x8C,0xAD,0x00,0xFF,0x90,0xAC,0x02,0xFF,0x8A,0xAA,0x00,0xFF, + 0x90,0xAA,0x09,0xFF,0x89,0xAF,0x00,0xFF,0x88,0xAE,0x01,0xFF,0x91,0xAA,0x06,0xFF,0x86,0xA5,0x02,0xFF, + 0x83,0xA9,0x00,0xFF,0x85,0xAE,0x00,0xFF,0x88,0xAD,0x05,0xFF,0x8E,0xAF,0x00,0xFF,0x8D,0xA8,0x03,0xFF, + 0x8F,0xAC,0x06,0xFF,0x8D,0xAC,0x06,0xFF,0x8B,0xAE,0x0A,0xFF,0x8C,0xAD,0x00,0xFF,0x8B,0xB1,0x02,0xFF, + 0x89,0xAC,0x00,0xFF,0x74,0x94,0x0D,0xFF,0x56,0x6E,0x00,0xFF,0x56,0x7A,0x20,0xFF,0x31,0x59,0x50,0xFF, + 0x00,0x59,0xB3,0xFF,0x00,0x76,0xFF,0xFF,0x2C,0x89,0xB5,0xFF,0x3F,0x5E,0x3F,0xFF,0x24,0x34,0x19,0xFF, + 0x22,0x2E,0x00,0xFF,0x2E,0x3D,0x14,0xFF,0x35,0x64,0x5A,0xFF,0x19,0x67,0x8D,0xFF,0x0D,0x5A,0x92,0xFF, + 0x05,0x53,0x93,0xFF,0x04,0x4D,0xAB,0xFF,0x03,0x4F,0xAF,0xFF,0x02,0x52,0xAB,0xFF,0x00,0x52,0xAA,0xFF, + 0x02,0x55,0xB5,0xFF,0x08,0x54,0xAA,0xFF,0x00,0x50,0xB0,0xFF,0x00,0x56,0xAE,0xFF,0x01,0x77,0xFB,0xFF, + 0x3A,0x94,0xD2,0xFF,0x22,0x2B,0x10,0xFF,0x2E,0x2B,0x00,0xFF,0x57,0x78,0x03,0xFF,0x7A,0x99,0x00,0xFF, + 0x7D,0xA6,0x00,0xFF,0x8B,0xB1,0x0C,0xFF,0x86,0xA5,0x02,0xFF,0x80,0x9A,0x00,0xFF,0x61,0x75,0x00,0xFF, + 0x4E,0x62,0x0D,0xFF,0x52,0x75,0x1B,0xFF,0x46,0x51,0x03,0xFF,0x4A,0x51,0x0B,0xFF,0x6E,0x8E,0x00,0xFF, + 0x89,0xB0,0x00,0xFF,0x8F,0xAD,0x00,0xFF,0x8C,0xAC,0x00,0xFF,0x90,0xAF,0x00,0xFF,0x8D,0xAB,0x00,0xFF, + 0x86,0xAC,0x00,0xFF,0x91,0xAA,0x04,0xFF,0x8A,0xAC,0x00,0xFF,0x8A,0xAE,0x02,0xFF,0x85,0xA4,0x00,0xFF, + 0x7B,0x9E,0x00,0xFF,0x74,0x98,0x00,0xFF,0x84,0x9B,0x05,0xFF,0x3C,0x45,0x06,0xFF,0x54,0x68,0x07,0xFF, + 0x74,0x92,0x00,0xFF,0x85,0xA1,0x00,0xFF,0x90,0xAB,0x06,0xFF,0x8B,0xAB,0x00,0xFF,0x8B,0xAE,0x00,0xFF, + 0x8B,0xAB,0x00,0xFF,0x84,0xAA,0x00,0xFF,0x91,0xB0,0x00,0xFF,0x90,0xB4,0x0A,0xFF,0x90,0xA8,0x08,0xFF, + 0x6D,0x8A,0x1C,0xFF,0x2A,0x48,0x48,0xFF,0x0D,0x59,0xAF,0xFF,0x00,0x73,0xD8,0xFF,0x00,0x5C,0xB6,0xFF, + 0x07,0x71,0xE9,0xFF,0x00,0x86,0xF9,0xFF,0x0A,0x8E,0xF2,0xFF,0x24,0x78,0xD2,0xFF,0x2A,0x5C,0x8F,0xFF, + 0x14,0x5E,0x8F,0xFF,0x00,0x64,0xCA,0xFF,0x09,0x72,0xDB,0xFF,0x02,0x63,0xC2,0xFF,0x00,0x53,0xAD,0xFF, + 0x02,0x51,0xAD,0xFF,0x06,0x55,0xB4,0xFF,0x00,0x53,0xAD,0xFF,0x00,0x4E,0xAA,0xFF,0x00,0x53,0xAF,0xFF, + 0x02,0x4C,0xAB,0xFF,0x06,0x55,0xB1,0xFF,0x03,0x52,0xB1,0xFF,0x02,0x75,0xF2,0xFF,0x29,0x91,0xFF,0xFF, + 0x40,0x84,0x99,0xFF,0x38,0x42,0x1D,0xFF,0x20,0x30,0x03,0xFF,0x3D,0x49,0x0B,0xFF,0x4F,0x6A,0x00,0xFF, + 0x56,0x71,0x00,0xFF,0x5B,0x73,0x03,0xFF,0x4B,0x5D,0x13,0xFF,0x37,0x47,0x20,0xFF,0x23,0x46,0x6E,0xFF, + 0x1F,0x74,0xAB,0xFF,0x30,0x5B,0x3F,0xFF,0x17,0x22,0x00,0xFF,0x47,0x5A,0x09,0xFF,0x7B,0x9E,0x02,0xFF, + 0x8B,0xAC,0x00,0xFF,0x8B,0xAE,0x00,0xFF,0x8F,0xAA,0x00,0xFF,0x8C,0xAA,0x0A,0xFF,0x94,0xA9,0x04,0xFF, + 0x94,0xAB,0x05,0xFF,0x81,0xA5,0x00,0xFF,0x6F,0x95,0x02,0xFF,0x51,0x68,0x00,0xFF,0x38,0x46,0x08,0xFF, + 0x2B,0x38,0x0A,0xFF,0x28,0x2F,0x05,0xFF,0x2C,0x35,0x1A,0xFF,0x18,0x20,0x0B,0xFF,0x38,0x4C,0x05,0xFF, + 0x61,0x81,0x06,0xFF,0x81,0xA5,0x00,0xFF,0x90,0xAD,0x07,0xFF,0x8C,0xAA,0x00,0xFF,0x8A,0xAF,0x00,0xFF, + 0x93,0xAF,0x05,0xFF,0x89,0xA7,0x00,0xFF,0x9F,0xD4,0x00,0xFF,0xA7,0xCF,0x31,0xFF,0x42,0x77,0x4B,0xFF, + 0x08,0x40,0x6F,0xFF,0x00,0x54,0xAA,0xFF,0x00,0x56,0xB7,0xFF,0x00,0x50,0xAB,0xFF,0x00,0x58,0xB9,0xFF, + 0x06,0x68,0xC9,0xFF,0x00,0x68,0xDE,0xFF,0x09,0x86,0xFF,0xFF,0x00,0x6E,0xDE,0xFF,0x02,0x55,0xBB,0xFF, + 0x03,0x56,0xB6,0xFF,0x00,0x58,0xBE,0xFF,0x00,0x59,0xB2,0xFF,0x02,0x50,0xB2,0xFF,0x00,0x52,0xA3,0xFF, + 0x01,0x51,0xA8,0xFF,0x00,0x55,0xA7,0xFF,0x02,0x54,0xAA,0xFF,0x01,0x51,0xA8,0xFF,0x02,0x54,0xA8,0xFF, + 0x05,0x4E,0xAA,0xFF,0x00,0x54,0xA4,0xFF,0x00,0x57,0xB2,0xFF,0x00,0x76,0xF1,0xFF,0x0A,0x88,0xEE,0xFF, + 0x3C,0x94,0xD3,0xFF,0x46,0x7E,0x71,0xFF,0x44,0x61,0x31,0xFF,0x40,0x5C,0x29,0xFF,0x49,0x65,0x28,0xFF, + 0x54,0x84,0x54,0xFF,0x4D,0x94,0x82,0xFF,0x20,0x67,0x93,0xFF,0x06,0x60,0xC0,0xFF,0x00,0x87,0xFF,0xFF, + 0x36,0x85,0xC8,0xFF,0x32,0x50,0x2C,0xFF,0x47,0x58,0x11,0xFF,0x7B,0x9B,0x00,0xFF,0x8B,0xAC,0x00,0xFF, + 0x8A,0xB0,0x05,0xFF,0x90,0xAC,0x00,0xFF,0x8B,0xAC,0x00,0xFF,0x87,0xAB,0x00,0xFF,0x8B,0xB0,0x00,0xFF, + 0x8D,0xB3,0x06,0xFF,0x52,0x74,0x38,0xFF,0x30,0x5D,0x48,0xFF,0x33,0x61,0x5E,0xFF,0x35,0x5A,0x52,0xFF, + 0x2E,0x4F,0x32,0xFF,0x05,0x7C,0xDA,0xFF,0x2B,0x64,0x81,0xFF,0x2B,0x33,0x1E,0xFF,0x38,0x40,0x05,0xFF, + 0x68,0x88,0x00,0xFF,0x90,0xAE,0x01,0xFF,0x8D,0xA9,0x00,0xFF,0x8C,0xB1,0x01,0xFF,0x88,0xAF,0x00,0xFF, + 0x90,0xAB,0x00,0xFF,0xB0,0xD7,0x00,0xFF,0xC7,0xE2,0x35,0xFF,0x2E,0x5A,0x4B,0xFF,0x00,0x33,0x62,0xFF, + 0x01,0x53,0xA5,0xFF,0x02,0x51,0xAD,0xFF,0x09,0x50,0xA8,0xFF,0x04,0x50,0xB2,0xFF,0x01,0x4F,0xA1,0xFF, + 0x02,0x5A,0xB4,0xFF,0x00,0x63,0xCA,0xFF,0x00,0x67,0xBD,0xFF,0x03,0x5D,0xB5,0xFF,0x00,0x4D,0xA8,0xFF, + 0x05,0x54,0xB1,0xFF,0x00,0x54,0xAE,0xFF,0x02,0x4D,0xB2,0xFF,0x00,0x53,0xAA,0xFF,0x04,0x50,0xB0,0xFF, + 0x00,0x51,0xAF,0xFF,0x04,0x51,0xAB,0xFF,0x01,0x51,0xB0,0xFF,0x00,0x51,0xAB,0xFF,0x04,0x59,0xAC,0xFF, + 0x00,0x52,0xA8,0xFF,0x00,0x52,0xB7,0xFF,0x01,0x5E,0xAE,0xFF,0x0A,0x76,0xDB,0xFF,0x00,0x6E,0xE9,0xFF, + 0x04,0x7B,0xFD,0xFF,0x00,0x74,0xE7,0xFF,0x00,0x76,0xD7,0xFF,0x00,0x68,0xC8,0xFF,0x00,0x6C,0xDF,0xFF, + 0x00,0x76,0xEE,0xFF,0x00,0x6C,0xC9,0xFF,0x00,0x5A,0xBA,0xFF,0x01,0x69,0xE6,0xFF,0x25,0x73,0xB1,0xFF, + 0x41,0x5F,0x2B,0xFF,0x5B,0x74,0x18,0xFF,0x87,0xA6,0x02,0xFF,0x8F,0xA8,0x06,0xFF,0x87,0xAC,0x04,0xFF, + 0x8F,0xAC,0x04,0xFF,0x8C,0xAF,0x00,0xFF,0x89,0xAD,0x03,0xFF,0x90,0xBD,0x08,0xFF,0x7D,0xAA,0x0F,0xFF, + 0x19,0x48,0x72,0xFF,0x00,0x5D,0xAD,0xFF,0x02,0x7C,0xFF,0xFF,0x01,0x7E,0xFF,0xFF,0x02,0x82,0xFF,0xFF, + 0x00,0x7A,0xFF,0xFF,0x17,0x89,0xF9,0xFF,0x29,0x71,0xBB,0xFF,0x32,0x52,0x21,0xFF,0x43,0x4D,0x08,0xFF, + 0x7A,0x9D,0x00,0xFF,0x88,0xAD,0x08,0xFF,0x92,0xAA,0x00,0xFF,0x88,0xAB,0x06,0xFF,0x93,0xAF,0x00,0xFF, + 0x9D,0xCD,0x00,0xFF,0xCB,0xF8,0x2B,0xFF,0x29,0x55,0x58,0xFF,0x01,0x28,0x51,0xFF,0x08,0x4E,0xA6,0xFF, + 0x00,0x54,0xAD,0xFF,0x00,0x52,0xAC,0xFF,0x02,0x56,0xB0,0xFF,0x00,0x52,0xAC,0xFF,0x00,0x50,0xB4,0xFF, + 0x02,0x55,0xB5,0xFF,0x00,0x59,0xB1,0xFF,0x00,0x51,0xB4,0xFF,0x09,0x51,0xB7,0xFF,0x02,0x4E,0xA4,0xFF, + 0x00,0x55,0xB0,0xFF,0x00,0x53,0xA9,0xFF,0x00,0x54,0xA3,0xFF,0x07,0x4F,0xB1,0xFF,0x03,0x51,0xB5,0xFF, + 0x02,0x50,0xA3,0xFF,0x00,0x54,0xAD,0xFF,0x03,0x51,0xB3,0xFF,0x00,0x50,0xAD,0xFF,0x06,0x53,0xAD,0xFF, + 0x07,0x52,0xAF,0xFF,0x00,0x51,0xAE,0xFF,0x01,0x4D,0xAB,0xFF,0x00,0x54,0xAE,0xFF,0x00,0x5A,0xB4,0xFF, + 0x05,0x62,0xCA,0xFF,0x00,0x64,0xC8,0xFF,0x02,0x5E,0xB5,0xFF,0x00,0x4F,0xB2,0xFF,0x00,0x55,0xAF,0xFF, + 0x05,0x4E,0xB7,0xFF,0x00,0x4F,0xB4,0xFF,0x00,0x6F,0xD8,0xFF,0x37,0x62,0x8C,0xFF,0x27,0x32,0x10,0xFF, + 0x5C,0x7E,0x06,0xFF,0x8B,0xAD,0x00,0xFF,0x94,0xA7,0x00,0xFF,0x8F,0xB2,0x00,0xFF,0x8A,0xA7,0x00,0xFF, + 0x8A,0xAF,0x00,0xFF,0x99,0xB6,0x00,0xFF,0xA2,0xD5,0x14,0xFF,0x5A,0x76,0x4E,0xFF,0x06,0x24,0x56,0xFF, + 0x04,0x46,0x94,0xFF,0x00,0x53,0xB1,0xFF,0x00,0x59,0xB2,0xFF,0x00,0x73,0xD6,0xFF,0x00,0x59,0xB9,0xFF, + 0x01,0x72,0xDA,0xFF,0x0B,0x84,0xF9,0xFF,0x30,0x72,0x92,0xFF,0x25,0x32,0x00,0xFF,0x60,0x72,0x06,0xFF, + 0x82,0xA4,0x05,0xFF,0x8B,0xAD,0x00,0xFF,0x8C,0xAA,0x00,0xFF,0x8D,0xAE,0x05,0xFF,0xA6,0xCD,0x00,0xFF, + 0xAE,0xF9,0x2A,0xFF,0x43,0x72,0x62,0xFF,0x07,0x28,0x5D,0xFF,0x00,0x53,0x9E,0xFF,0x05,0x51,0xB1,0xFF, + 0x00,0x55,0xAB,0xFF,0x03,0x52,0xAE,0xFF,0x05,0x55,0xAE,0xFF,0x00,0x53,0xAB,0xFF,0x00,0x51,0xAC,0xFF, + 0x00,0x53,0xAF,0xFF,0x00,0x52,0xAE,0xFF,0x07,0x4F,0xB1,0xFF,0x00,0x53,0xB5,0xFF,0x01,0x53,0xA7,0xFF, + 0x00,0x54,0xA5,0xFF,0x00,0x51,0xAB,0xFF,0x00,0x54,0xB3,0xFF,0x02,0x52,0xB1,0xFF,0x03,0x54,0xB0,0xFF, + 0x00,0x53,0xA8,0xFF,0x00,0x54,0xAE,0xFF,0x02,0x51,0xAD,0xFF,0x01,0x51,0xAA,0xFF,0x00,0x54,0xAB,0xFF, + 0x00,0x52,0xAC,0xFF,0x07,0x54,0xB0,0xFF,0x00,0x4E,0xAB,0xFF,0x00,0x55,0xB1,0xFF,0x05,0x54,0xB1,0xFF, + 0x04,0x4D,0xA9,0xFF,0x00,0x54,0xB0,0xFF,0x04,0x51,0xAD,0xFF,0x07,0x4F,0xB3,0xFF,0x00,0x53,0xB1,0xFF, + 0x03,0x58,0xB5,0xFF,0x00,0x74,0xE8,0xFF,0x2D,0x63,0x87,0xFF,0x2C,0x32,0x18,0xFF,0x69,0x82,0x03,0xFF, + 0x8B,0xAC,0x00,0xFF,0x91,0xAE,0x00,0xFF,0x87,0xB0,0x00,0xFF,0x8D,0xAB,0x00,0xFF,0x8D,0xAC,0x08,0xFF, + 0xA9,0xCE,0x0E,0xFF,0xBF,0xE6,0x35,0xFF,0x59,0x69,0x4C,0xFF,0x0A,0x2B,0x56,0xFF,0x00,0x47,0x94,0xFF, + 0x00,0x53,0xAA,0xFF,0x03,0x54,0xB0,0xFF,0x02,0x4F,0xA7,0xFF,0x00,0x54,0xAB,0xFF,0x00,0x52,0xB1,0xFF, + 0x00,0x79,0xEC,0xFF,0x1D,0x7D,0xC7,0xFF,0x33,0x40,0x15,0xFF,0x40,0x52,0x00,0xFF,0x78,0x9D,0x00,0xFF, + 0x90,0xAB,0x00,0xFF,0x8B,0xB1,0x00,0xFF,0x8D,0xA2,0x05,0xFF,0x9E,0xC3,0x04,0xFF,0xC0,0xED,0x16,0xFF, + 0x60,0x8F,0x5B,0xFF,0x04,0x37,0x79,0xFF,0x00,0x58,0xA7,0xFF,0x05,0x51,0xB1,0xFF,0x02,0x51,0xAE,0xFF, + 0x00,0x50,0xA9,0xFF,0x00,0x50,0xAB,0xFF,0x00,0x51,0xAB,0xFF,0x01,0x53,0xA9,0xFF,0x02,0x53,0xAE,0xFF, + 0x00,0x52,0xAF,0xFF,0x00,0x52,0xAD,0xFF,0x02,0x51,0xAE,0xFF,0x02,0x51,0xB0,0xFF,0x04,0x51,0xA9,0xFF, + 0x08,0x54,0xAA,0xFF,0x06,0x4E,0xB0,0xFF,0x06,0x4C,0xAC,0xFF,0x02,0x4F,0xA7,0xFF,0x00,0x53,0xB1,0xFF, + 0x00,0x50,0xAC,0xFF,0x06,0x53,0xAF,0xFF,0x06,0x51,0xAE,0xFF,0x01,0x52,0xAD,0xFF,0x01,0x52,0xAE,0xFF, + 0x03,0x4D,0xAC,0xFF,0x04,0x4E,0xAD,0xFF,0x01,0x52,0xAD,0xFF,0x00,0x52,0xB3,0xFF,0x00,0x52,0xAC,0xFF, + 0x02,0x53,0xAF,0xFF,0x00,0x52,0xA8,0xFF,0x00,0x54,0xAE,0xFF,0x00,0x53,0xB0,0xFF,0x00,0x5D,0xBA,0xFF, + 0x0B,0x7D,0xD5,0xFF,0x3F,0x7C,0x5B,0xFF,0x38,0x47,0x06,0xFF,0x76,0x93,0x05,0xFF,0x8D,0xAD,0x00,0xFF, + 0x8D,0xA9,0x00,0xFF,0x88,0xAF,0x00,0xFF,0x8E,0xAC,0x00,0xFF,0x8D,0xAD,0x00,0xFF,0xA3,0xC9,0x00,0xFF, + 0xC6,0xED,0x38,0xFF,0x4E,0x6D,0x4D,0xFF,0x00,0x1D,0x39,0xFF,0x04,0x4B,0x99,0xFF,0x00,0x51,0xAA,0xFF, + 0x02,0x56,0xAE,0xFF,0x00,0x50,0xAF,0xFF,0x08,0x55,0xAF,0xFF,0x03,0x50,0xAC,0xFF,0x00,0x73,0xDC,0xFF, + 0x13,0x7A,0xD6,0xFF,0x44,0x58,0x27,0xFF,0x4E,0x69,0x02,0xFF,0x80,0x9A,0x01,0xFF,0x8E,0xAF,0x00,0xFF, + 0x8B,0xB1,0x00,0xFF,0x90,0xAA,0x08,0xFF,0x92,0xB1,0x00,0xFF,0xB3,0xDD,0x0D,0xFF,0x60,0x8D,0x4A,0xFF, + 0x01,0x41,0x71,0xFF,0x00,0x49,0x9A,0xFF,0x01,0x51,0xAA,0xFF,0x07,0x4F,0xB3,0xFF,0x02,0x53,0xAF,0xFF, + 0x00,0x51,0xB4,0xFF,0x04,0x52,0xB7,0xFF,0x06,0x50,0xAF,0xFF,0x05,0x4E,0xAC,0xFF,0x05,0x50,0xAD,0xFF, + 0x00,0x54,0xA5,0xFF,0x04,0x4F,0xAA,0xFF,0x00,0x52,0xAE,0xFF,0x00,0x54,0xB0,0xFF,0x00,0x55,0xAD,0xFF, + 0x00,0x55,0xA5,0xFF,0x01,0x56,0xA9,0xFF,0x02,0x53,0xAE,0xFF,0x01,0x50,0xAF,0xFF,0x00,0x53,0xAD,0xFF, + 0x00,0x4E,0xAB,0xFF,0x06,0x52,0xB4,0xFF,0x00,0x4F,0xAD,0xFF,0x00,0x55,0xAC,0xFF,0x00,0x55,0xA8,0xFF, + 0x00,0x53,0xA9,0xFF,0x00,0x55,0xAC,0xFF,0x00,0x52,0xAE,0xFF,0x00,0x55,0xA9,0xFF,0x00,0x52,0xB0,0xFF, + 0x02,0x53,0xAC,0xFF,0x03,0x55,0xA9,0xFF,0x01,0x4F,0xB3,0xFF,0x02,0x5C,0xB4,0xFF,0x10,0x78,0xCD,0xFF, + 0x33,0x65,0x5A,0xFF,0x36,0x45,0x0A,0xFF,0x75,0x93,0x01,0xFF,0x8C,0xAE,0x00,0xFF,0x8E,0xA9,0x02,0xFF, + 0x8A,0xB0,0x05,0xFF,0x8E,0xAB,0x01,0xFF,0x8C,0xAD,0x00,0xFF,0xAA,0xCF,0x03,0xFF,0xCB,0xF4,0x2E,0xFF, + 0x54,0x83,0x59,0xFF,0x01,0x1B,0x3E,0xFF,0x01,0x42,0x82,0xFF,0x04,0x54,0xAD,0xFF,0x00,0x4D,0xAF,0xFF, + 0x01,0x55,0xAF,0xFF,0x03,0x4F,0xAF,0xFF,0x01,0x55,0xAD,0xFF,0x00,0x69,0xDC,0xFF,0x16,0x68,0xA0,0xFF, + 0x47,0x56,0x11,0xFF,0x75,0x97,0x02,0xFF,0x84,0xA1,0x09,0xFF,0x88,0xAE,0x01,0xFF,0x87,0xAC,0x00,0xFF, + 0x8F,0xAC,0x00,0xFF,0x8D,0xB9,0x02,0xFF,0x9C,0xC5,0x13,0xFF,0x68,0xB0,0x40,0xFF,0x0F,0x3C,0x65,0xFF, + 0x00,0x44,0x85,0xFF,0x04,0x52,0xA7,0xFF,0x01,0x51,0xA8,0xFF,0x00,0x55,0xA7,0xFF,0x00,0x53,0xA5,0xFF, + 0x00,0x53,0xA6,0xFF,0x00,0x53,0xA6,0xFF,0x00,0x51,0xA9,0xFF,0x00,0x53,0xAF,0xFF,0x00,0x55,0xB1,0xFF, + 0x00,0x53,0xAD,0xFF,0x00,0x52,0xA8,0xFF,0x02,0x53,0xAE,0xFF,0x00,0x4E,0xAB,0xFF,0x02,0x54,0xAA,0xFF, + 0x00,0x53,0xAD,0xFF,0x00,0x53,0xB3,0xFF,0x00,0x50,0xA7,0xFF,0x00,0x57,0xAA,0xFF,0x00,0x50,0xAC,0xFF, + 0x04,0x54,0xB5,0xFF,0x01,0x52,0xAE,0xFF,0x02,0x54,0xAA,0xFF,0x02,0x53,0xA5,0xFF,0x03,0x50,0xA8,0xFF, + 0x05,0x4F,0xAE,0xFF,0x0B,0x51,0xB0,0xFF,0x09,0x50,0xA8,0xFF,0x00,0x55,0xAA,0xFF,0x00,0x53,0xAD,0xFF, + 0x03,0x54,0xA6,0xFF,0x00,0x58,0xBD,0xFF,0x0D,0x62,0xA5,0xFF,0x1E,0x62,0xA3,0xFF,0x34,0x5A,0x5D,0xFF, + 0x50,0x63,0x14,0xFF,0x79,0x97,0x01,0xFF,0x8D,0xAF,0x01,0xFF,0x90,0xAE,0x01,0xFF,0x8A,0xAE,0x06,0xFF, + 0x8C,0xA9,0x00,0xFF,0x8B,0xAC,0x00,0xFF,0x9A,0xBF,0x00,0xFF,0xC9,0xF2,0x2C,0xFF,0x63,0x96,0x4B,0xFF, + 0x03,0x1A,0x3C,0xFF,0x04,0x37,0x76,0xFF,0x00,0x51,0xAF,0xFF,0x03,0x54,0xAD,0xFF,0x00,0x50,0xAB,0xFF, + 0x00,0x52,0xAE,0xFF,0x00,0x56,0xAB,0xFF,0x08,0x65,0xE6,0xFF,0x30,0x68,0x69,0xFF,0x53,0x5A,0x00,0xFF, + 0x82,0xA7,0x00,0xFF,0x82,0xAE,0x01,0xFF,0x90,0xAE,0x00,0xFF,0x8D,0xAE,0x09,0xFF,0x87,0xAA,0x00,0xFF, + 0x91,0xB8,0x03,0xFF,0x89,0xB5,0x08,0xFF,0x89,0xD7,0x12,0xFF,0x18,0x4C,0x71,0xFF,0x00,0x3C,0x73,0xFF, + 0x02,0x51,0xB6,0xFF,0x00,0x50,0xA9,0xFF,0x05,0x51,0xB1,0xFF,0x04,0x53,0xB0,0xFF,0x01,0x55,0xAF,0xFF, + 0x00,0x53,0xB0,0xFF,0x00,0x53,0xAD,0xFF,0x00,0x53,0xA9,0xFF,0x03,0x50,0xAC,0xFF,0x00,0x58,0xA3,0xFF, + 0x00,0x4F,0xA8,0xFF,0x03,0x4D,0xA6,0xFF,0x04,0x4F,0xAA,0xFF,0x01,0x54,0xB4,0xFF,0x00,0x53,0xAF,0xFF, + 0x00,0x54,0xAB,0xFF,0x05,0x51,0xAF,0xFF,0x02,0x53,0xAC,0xFF,0x01,0x52,0xAB,0xFF,0x00,0x4E,0xA3,0xFF, + 0x03,0x53,0xA8,0xFF,0x01,0x51,0xA6,0xFF,0x00,0x53,0xAB,0xFF,0x00,0x57,0xB1,0xFF,0x00,0x52,0xB1,0xFF, + 0x00,0x51,0xAF,0xFF,0x06,0x50,0xA9,0xFF,0x01,0x52,0xAD,0xFF,0x04,0x4D,0xB3,0xFF,0x06,0x50,0xBB,0xFF, + 0x00,0x70,0xD3,0xFF,0x16,0x81,0xB7,0xFF,0x34,0x68,0x5C,0xFF,0x46,0x69,0x27,0xFF,0x7C,0x9B,0x02,0xFF, + 0x88,0xA9,0x02,0xFF,0x8E,0xAF,0x08,0xFF,0x8C,0xAD,0x00,0xFF,0x89,0xAB,0x00,0xFF,0x8E,0xAC,0x00,0xFF, + 0x8E,0xAE,0x03,0xFF,0x90,0xB5,0x03,0xFF,0xC1,0xEA,0x14,0xFF,0x8D,0xB9,0x2E,0xFF,0x00,0x17,0x2F,0xFF, + 0x00,0x28,0x56,0xFF,0x00,0x51,0xAB,0xFF,0x04,0x51,0xA9,0xFF,0x07,0x54,0xAE,0xFF,0x00,0x50,0xAC,0xFF, + 0x00,0x55,0xAC,0xFF,0x1A,0x60,0xA8,0xFF,0x47,0x68,0x31,0xFF,0x66,0x7B,0x00,0xFF,0x7E,0xA7,0x00,0xFF, + 0x87,0xAD,0x00,0xFF,0x92,0xAA,0x00,0xFF,0x8E,0xB0,0x00,0xFF,0x8A,0xB4,0x00,0xFF,0x97,0xAF,0x01,0xFF, + 0x89,0xB1,0x12,0xFF,0xA3,0xD0,0x04,0xFF,0x30,0x84,0x6C,0xFF,0x00,0x32,0x69,0xFF,0x00,0x51,0xA5,0xFF, + 0x00,0x57,0xB0,0xFF,0x02,0x4E,0xAE,0xFF,0x00,0x4F,0xB0,0xFF,0x00,0x51,0xB1,0xFF,0x06,0x53,0xAF,0xFF, + 0x05,0x50,0xA3,0xFF,0x00,0x43,0x8A,0xFF,0x04,0x34,0x7C,0xFF,0x04,0x26,0x4B,0xFF,0x05,0x22,0x40,0xFF, + 0x01,0x22,0x41,0xFF,0x00,0x34,0x66,0xFF,0x00,0x43,0x8E,0xFF,0x04,0x50,0xA4,0xFF,0x01,0x51,0xA8,0xFF, + 0x00,0x52,0xAC,0xFF,0x07,0x4F,0xB3,0xFF,0x00,0x50,0xA9,0xFF,0x02,0x51,0x9C,0xFF,0x00,0x43,0x88,0xFF, + 0x00,0x34,0x7A,0xFF,0x01,0x41,0x88,0xFF,0x00,0x42,0x8D,0xFF,0x00,0x4A,0x98,0xFF,0x01,0x54,0xB4,0xFF, + 0x03,0x54,0xAF,0xFF,0x05,0x50,0xAD,0xFF,0x02,0x52,0xA9,0xFF,0x00,0x50,0xB3,0xFF,0x00,0x6A,0xC3,0xFF, + 0x0C,0x7A,0xD1,0xFF,0x35,0x5F,0x49,0xFF,0x3A,0x52,0x04,0xFF,0x7F,0x9F,0x00,0xFF,0x8A,0xAC,0x00,0xFF, + 0x8D,0xAD,0x04,0xFF,0x8B,0xAD,0x00,0xFF,0x8C,0xAC,0x01,0xFF,0x8D,0xAD,0x04,0xFF,0x8B,0xAA,0x04,0xFF, + 0x8F,0xB4,0x04,0xFF,0xB3,0xDC,0x00,0xFF,0xD7,0xFF,0x31,0xFF,0x12,0x30,0x2E,0xFF,0x00,0x24,0x3E,0xFF, + 0x00,0x52,0xA3,0xFF,0x09,0x55,0xB3,0xFF,0x00,0x4E,0xA7,0xFF,0x00,0x55,0xB2,0xFF,0x0E,0x61,0xA7,0xFF, + 0x3E,0x66,0x44,0xFF,0x64,0x7D,0x08,0xFF,0x80,0xA2,0x03,0xFF,0x89,0xB1,0x00,0xFF,0x92,0xAA,0x0A,0xFF, + 0x90,0xAE,0x01,0xFF,0x8A,0xA9,0x05,0xFF,0x8C,0xAD,0x04,0xFF,0x93,0xB5,0x00,0xFF,0x90,0xAC,0x00,0xFF, + 0xA4,0xCD,0x05,0xFF,0x6A,0xAA,0x38,0xFF,0x05,0x31,0x60,0xFF,0x01,0x40,0x8D,0xFF,0x00,0x4A,0x97,0xFF, + 0x04,0x48,0x91,0xFF,0x05,0x55,0xAA,0xFF,0x00,0x51,0xA6,0xFF,0x01,0x42,0x82,0xFF,0x03,0x40,0x6D,0xFF, + 0x0A,0x45,0x65,0xFF,0x2D,0x52,0x5B,0xFF,0x27,0x4F,0x51,0xFF,0x22,0x3D,0x38,0xFF,0x19,0x2F,0x3C,0xFF, + 0x08,0x2B,0x4B,0xFF,0x00,0x2C,0x4B,0xFF,0x00,0x2A,0x4F,0xFF,0x01,0x3B,0x7B,0xFF,0x04,0x52,0xA5,0xFF, + 0x00,0x4F,0xB2,0xFF,0x00,0x53,0xB4,0xFF,0x03,0x51,0xA4,0xFF,0x00,0x32,0x69,0xFF,0x00,0x1B,0x30,0xFF, + 0x0C,0x24,0x28,0xFF,0x07,0x22,0x35,0xFF,0x01,0x1D,0x45,0xFF,0x00,0x28,0x5A,0xFF,0x00,0x3B,0x75,0xFF, + 0x00,0x43,0x8C,0xFF,0x01,0x52,0xA4,0xFF,0x03,0x53,0xB2,0xFF,0x03,0x57,0xAD,0xFF,0x0D,0x56,0x9A,0xFF, + 0x27,0x36,0x23,0xFF,0x3F,0x4A,0x06,0xFF,0x67,0x7F,0x03,0xFF,0x7F,0x9E,0x00,0xFF,0x84,0xA3,0x00,0xFF, + 0x85,0xA6,0x00,0xFF,0x8D,0xAE,0x00,0xFF,0x8E,0xAE,0x01,0xFF,0x8C,0xAE,0x00,0xFF,0x86,0xAB,0x00,0xFF, + 0x9C,0xBF,0x03,0xFF,0xCE,0xFE,0x08,0xFF,0x5E,0x84,0x5B,0xFF,0x05,0x28,0x48,0xFF,0x01,0x49,0x93,0xFF, + 0x00,0x50,0xA2,0xFF,0x00,0x54,0xB4,0xFF,0x04,0x6C,0xC1,0xFF,0x2F,0x71,0x93,0xFF,0x6A,0x79,0x10,0xFF, + 0x7F,0xA4,0x00,0xFF,0x8F,0xAB,0x01,0xFF,0x91,0xAF,0x01,0xFF,0x8B,0xA8,0x00,0xFF,0x87,0xAE,0x00,0xFF, + 0x92,0xAE,0x01,0xFF,0x80,0xA3,0x00,0xFF,0x80,0xA5,0x00,0xFF,0x77,0x9D,0x00,0xFF,0x8F,0xB4,0x02,0xFF, + 0x87,0xA4,0x16,0xFF,0x01,0x21,0x30,0xFF,0x00,0x2D,0x52,0xFF,0x00,0x21,0x3D,0xFF,0x02,0x1C,0x35,0xFF, + 0x00,0x30,0x6E,0xFF,0x02,0x3D,0x83,0xFF,0x26,0x4E,0x5A,0xFF,0x47,0x75,0x47,0xFF,0x65,0x9F,0x39,0xFF, + 0x9E,0xCC,0x23,0xFF,0xC0,0xED,0x20,0xFF,0xB7,0xE0,0x00,0xFF,0xB4,0xE5,0x0D,0xFF,0x85,0xC1,0x2E,0xFF, + 0x50,0x7E,0x4F,0xFF,0x08,0x23,0x34,0xFF,0x00,0x27,0x5C,0xFF,0x00,0x4C,0x9A,0xFF,0x00,0x56,0xB2,0xFF, + 0x02,0x61,0xCB,0xFF,0x00,0x52,0xB3,0xFF,0x1D,0x59,0x7E,0xFF,0x4A,0x71,0x45,0xFF,0x5D,0x83,0x2E,0xFF, + 0x62,0x8B,0x4F,0xFF,0x30,0x5C,0x4B,0xFF,0x0A,0x29,0x48,0xFF,0x14,0x3B,0x5C,0xFF,0x0A,0x32,0x4B,0xFF, + 0x00,0x29,0x5B,0xFF,0x00,0x31,0x6C,0xFF,0x03,0x3E,0x84,0xFF,0x1B,0x46,0x4D,0xFF,0x1F,0x26,0x16,0xFF, + 0x2C,0x2E,0x00,0xFF,0x27,0x33,0x05,0xFF,0x43,0x51,0x04,0xFF,0x43,0x54,0x06,0xFF,0x47,0x59,0x03,0xFF, + 0x59,0x6F,0x02,0xFF,0x63,0x79,0x0A,0xFF,0x6A,0x85,0x00,0xFF,0x7D,0x9C,0x00,0xFF,0x89,0xA4,0x07,0xFF, + 0xBD,0xF1,0x00,0xFF,0x60,0x88,0x54,0xFF,0x00,0x25,0x46,0xFF,0x05,0x40,0x84,0xFF,0x00,0x53,0xA8,0xFF, + 0x00,0x5A,0xB4,0xFF,0x00,0x77,0xD5,0xFF,0x38,0x74,0x36,0xFF,0x45,0x4C,0x00,0xFF,0x6F,0x85,0x07,0xFF, + 0x77,0xA1,0x00,0xFF,0x80,0xA5,0x00,0xFF,0x86,0xA7,0x00,0xFF,0x85,0xA4,0x00,0xFF,0x79,0x9A,0x01,0xFF, + 0x6A,0x7D,0x07,0xFF,0x4F,0x69,0x08,0xFF,0x53,0x69,0x00,0xFF,0x5B,0x74,0x0C,0xFF,0x60,0x88,0x28,0xFF, + 0x0D,0x25,0x27,0xFF,0x0B,0x34,0x50,0xFF,0x22,0x4B,0x47,0xFF,0x0F,0x2B,0x2F,0xFF,0x3B,0x5A,0x21,0xFF, + 0x6D,0x8F,0x42,0xFF,0x97,0xBC,0x1E,0xFF,0xB2,0xD7,0x0D,0xFF,0xA9,0xD9,0x00,0xFF,0xA1,0xCD,0x00,0xFF, + 0xA7,0xCC,0x00,0xFF,0x92,0xC1,0x00,0xFF,0xA4,0xCE,0x00,0xFF,0xC9,0xF1,0x05,0xFF,0xC1,0xF0,0x02,0xFF, + 0x4A,0x75,0x25,0xFF,0x03,0x24,0x4D,0xFF,0x00,0x4B,0x9D,0xFF,0x03,0x53,0xAA,0xFF,0x00,0x69,0xE0,0xFF, + 0x17,0x65,0xAD,0xFF,0x73,0x9B,0x16,0xFF,0xA6,0xCC,0x05,0xFF,0xC3,0xEE,0x0B,0xFF,0xCB,0xFF,0x00,0xFF, + 0xCD,0xFE,0x02,0xFF,0xA9,0xD6,0x17,0xFF,0x87,0xBF,0x20,0xFF,0x66,0x97,0x56,0xFF,0x31,0x83,0x6D,0xFF, + 0x31,0x6D,0x6E,0xFF,0x4B,0x8D,0x7F,0xFF,0x74,0x99,0x25,0xFF,0x53,0x89,0x2B,0xFF,0x1C,0x3D,0x20,0xFF, + 0x16,0x31,0x3A,0xFF,0x16,0x5E,0x77,0xFF,0x36,0x71,0x6F,0xFF,0x42,0x62,0x31,0xFF,0x3E,0x47,0x1C,0xFF, + 0x1E,0x29,0x09,0xFF,0x29,0x30,0x00,0xFF,0x4B,0x58,0x09,0xFF,0x60,0x76,0x00,0xFF,0x75,0x8E,0x0E,0xFF, + 0x35,0x4D,0x19,0xFF,0x00,0x22,0x48,0xFF,0x04,0x43,0x93,0xFF,0x00,0x4F,0xAA,0xFF,0x01,0x58,0xB7,0xFF, + 0x10,0x8D,0xF9,0xFF,0x34,0x77,0xA4,0xFF,0x33,0x46,0x19,0xFF,0x3B,0x48,0x03,0xFF,0x4C,0x69,0x00,0xFF, + 0x59,0x74,0x00,0xFF,0x5B,0x6E,0x00,0xFF,0x64,0x7E,0x00,0xFF,0x54,0x6B,0x10,0xFF,0x41,0x5A,0x18,0xFF, + 0x49,0x69,0x3A,0xFF,0x54,0x8F,0x63,0xFF,0x48,0x96,0x86,0xFF,0x2E,0x92,0xCD,0xFF,0x33,0x76,0x90,0xFF, + 0x53,0x83,0x37,0xFF,0x99,0xCA,0x30,0xFF,0xA0,0xD0,0x24,0xFF,0x9F,0xCF,0x0B,0xFF,0xAA,0xDC,0x00,0xFF, + 0x99,0xC1,0x00,0xFF,0x8F,0xB0,0x01,0xFF,0x8B,0xB1,0x00,0xFF,0x8B,0xAE,0x0C,0xFF,0x92,0xA8,0x00,0xFF, + 0x8E,0xAA,0x00,0xFF,0x8D,0xB2,0x00,0xFF,0x91,0xB4,0x02,0xFF,0x7D,0xAB,0x0A,0xFF,0x1E,0x3C,0x1A,0xFF, + 0x03,0x28,0x5C,0xFF,0x00,0x53,0xA5,0xFF,0x01,0x50,0xAD,0xFF,0x00,0x74,0xEF,0xFF,0x10,0x64,0xAA,0xFF, + 0x3D,0x4A,0x2E,0xFF,0x5C,0x6D,0x03,0xFF,0x81,0xA9,0x00,0xFF,0x94,0xB7,0x01,0xFF,0x99,0xBF,0x00,0xFF, + 0xA4,0xC9,0x00,0xFF,0xB7,0xE0,0x00,0xFF,0xC8,0xEF,0x02,0xFF,0xBB,0xF2,0x01,0xFF,0xBF,0xF0,0x00,0xFF, + 0xC2,0xFB,0x00,0xFF,0xCF,0xF6,0x00,0xFF,0xA4,0xDB,0x35,0xFF,0x32,0x7A,0x86,0xFF,0x02,0x46,0x99,0xFF, + 0x00,0x70,0xEB,0xFF,0x00,0x7F,0xFF,0xFF,0x15,0x88,0xFB,0xFF,0x42,0x97,0xCE,0xFF,0x4C,0x8B,0x78,0xFF, + 0x35,0x60,0x2B,0xFF,0x43,0x59,0x10,0xFF,0x4C,0x61,0x26,0xFF,0x27,0x47,0x30,0xFF,0x03,0x37,0x4F,0xFF, + 0x00,0x45,0x81,0xFF,0x00,0x4F,0x9E,0xFF,0x00,0x58,0xB1,0xFF,0x01,0x64,0xC2,0xFF,0x00,0x72,0xE5,0xFF, + 0x09,0x85,0xFF,0xFF,0x1E,0x77,0xD1,0xFF,0x48,0x73,0x48,0xFF,0x4F,0x5C,0x16,0xFF,0x4C,0x59,0x24,0xFF, + 0x42,0x59,0x25,0xFF,0x54,0x73,0x3A,0xFF,0x4C,0x85,0x5A,0xFF,0x1F,0x73,0x98,0xFF,0x0E,0x6D,0xCB,0xFF, + 0x00,0x75,0xEF,0xFF,0x03,0x77,0xFE,0xFF,0x00,0x7C,0xF8,0xFF,0x4D,0xAD,0xA2,0xFF,0x70,0x8D,0x17,0xFF, + 0x85,0xA4,0x09,0xFF,0x8C,0xB4,0x00,0xFF,0x8B,0xB2,0x01,0xFF,0x86,0xA5,0x01,0xFF,0x90,0xAF,0x00,0xFF, + 0x8F,0xAF,0x06,0xFF,0x8F,0xAC,0x06,0xFF,0x8A,0xAE,0x00,0xFF,0x8C,0xB0,0x06,0xFF,0x93,0xAB,0x00,0xFF, + 0x92,0xB0,0x02,0xFF,0x8B,0xAB,0x0C,0xFF,0x4A,0x85,0x55,0xFF,0x12,0x4A,0x6F,0xFF,0x0A,0x47,0x98,0xFF, + 0x00,0x54,0xA9,0xFF,0x00,0x53,0xA9,0xFF,0x00,0x71,0xE3,0xFF,0x00,0x6B,0xBE,0xFF,0x25,0x25,0x0D,0xFF, + 0x27,0x35,0x00,0xFF,0x71,0x92,0x00,0xFF,0x8B,0xB0,0x0A,0xFF,0x90,0xAE,0x00,0xFF,0x8B,0xAB,0x08,0xFF, + 0x8F,0xAB,0x00,0xFF,0x96,0xB4,0x00,0xFF,0x98,0xB6,0x08,0xFF,0x9B,0xBE,0x02,0xFF,0x98,0xBB,0x00,0xFF, + 0xAF,0xD1,0x08,0xFF,0xAA,0xEA,0x1A,0xFF,0x3A,0x5F,0x4D,0xFF,0x00,0x30,0x6C,0xFF,0x00,0x58,0xAA,0xFF, + 0x00,0x5C,0xB0,0xFF,0x00,0x69,0xDF,0xFF,0x06,0x83,0xFF,0xFF,0x12,0x90,0xF7,0xFF,0x0A,0x76,0xD8,0xFF, + 0x37,0x98,0xCF,0xFF,0x3D,0x99,0xD8,0xFF,0x1F,0x72,0xB4,0xFF,0x02,0x4D,0x90,0xFF,0x00,0x44,0x8F,0xFF, + 0x00,0x48,0x9F,0xFF,0x00,0x53,0xAB,0xFF,0x00,0x5B,0xAE,0xFF,0x02,0x56,0xB6,0xFF,0x07,0x6B,0xCB,0xFF, + 0x03,0x76,0xF3,0xFF,0x09,0x86,0xFC,0xFF,0x1C,0x98,0xBE,0xFF,0x20,0x7A,0xB9,0xFF,0x20,0x79,0xB1,0xFF, + 0x0E,0x78,0xCE,0xFF,0x0A,0x6B,0xC9,0xFF,0x01,0x65,0xBD,0xFF,0x0F,0x55,0xB4,0xFF,0x03,0x52,0xB1,0xFF, + 0x00,0x54,0xB3,0xFF,0x04,0x76,0xF0,0xFF,0x25,0x89,0xE1,0xFF,0x4D,0x71,0x33,0xFF,0x41,0x4F,0x00,0xFF, + 0x6A,0x86,0x00,0xFF,0x82,0xA5,0x03,0xFF,0x91,0xAC,0x00,0xFF,0x8D,0xA9,0x00,0xFF,0x89,0xAB,0x00,0xFF, + 0x91,0xAE,0x00,0xFF,0x8A,0xAC,0x00,0xFF,0x84,0xB1,0x00,0xFF,0x93,0xB3,0x00,0xFF,0x9E,0xBE,0x00,0xFF, + 0x70,0x8D,0x16,0xFF,0x13,0x55,0x6D,0xFF,0x00,0x56,0xA2,0xFF,0x00,0x4F,0xB0,0xFF,0x03,0x50,0xAA,0xFF, + 0x00,0x52,0xB6,0xFF,0x02,0x69,0xE0,0xFF,0x00,0x7A,0xF8,0xFF,0x32,0x48,0x31,0xFF,0x07,0x15,0x00,0xFF, + 0x61,0x79,0x00,0xFF,0x87,0xAB,0x03,0xFF,0x8D,0xA8,0x03,0xFF,0x8E,0xAF,0x00,0xFF,0x8C,0xA6,0x04,0xFF, + 0x8A,0xAD,0x00,0xFF,0x87,0xAE,0x05,0xFF,0x87,0xAD,0x08,0xFF,0x8C,0xB3,0x00,0xFF,0x9F,0xC3,0x00,0xFF, + 0x84,0xBE,0x2C,0xFF,0x1C,0x4B,0x69,0xFF,0x00,0x3C,0x79,0xFF,0x00,0x52,0x9E,0xFF,0x04,0x4E,0xA3,0xFF, + 0x00,0x52,0xB2,0xFF,0x00,0x5C,0xB7,0xFF,0x00,0x67,0xC2,0xFF,0x01,0x73,0xE5,0xFF,0x00,0x73,0xDD,0xFF, + 0x00,0x73,0xEB,0xFF,0x07,0x76,0xEC,0xFF,0x04,0x62,0xC2,0xFF,0x00,0x51,0xA0,0xFF,0x05,0x53,0xA5,0xFF, + 0x03,0x52,0xAF,0xFF,0x05,0x50,0xB5,0xFF,0x00,0x55,0xAC,0xFF,0x00,0x51,0xAE,0xFF,0x00,0x59,0xAE,0xFF, + 0x06,0x71,0xD3,0xFF,0x00,0x67,0xDE,0xFF,0x00,0x68,0xE1,0xFF,0x08,0x78,0xDA,0xFF,0x00,0x6C,0xCB,0xFF, + 0x03,0x55,0xB9,0xFF,0x00,0x55,0xB3,0xFF,0x00,0x51,0xA7,0xFF,0x02,0x4C,0xAF,0xFF,0x04,0x52,0xB7,0xFF, + 0x00,0x58,0xB0,0xFF,0x00,0x78,0xEC,0xFF,0x20,0x76,0xB3,0xFF,0x26,0x38,0x28,0xFF,0x40,0x55,0x00,0xFF, + 0x73,0x94,0x00,0xFF,0x91,0xAA,0x08,0xFF,0x90,0xAA,0x08,0xFF,0x8B,0xAF,0x07,0xFF,0x8F,0xAD,0x00,0xFF, + 0x89,0xAB,0x00,0xFF,0x8B,0xA8,0x02,0xFF,0x9D,0xC3,0x00,0xFF,0xA0,0xCA,0x10,0xFF,0x33,0x52,0x42,0xFF, + 0x00,0x34,0x63,0xFF,0x00,0x50,0xA0,0xFF,0x02,0x4F,0xA7,0xFF,0x06,0x55,0xB4,0xFF,0x01,0x50,0xAD,0xFF, + 0x00,0x63,0xBE,0xFF,0x00,0x81,0xF9,0xFF,0x38,0x78,0x9C,0xFF,0x10,0x15,0x00,0xFF,0x51,0x6D,0x00,0xFF, + 0x8C,0xA8,0x00,0xFF,0x8D,0xAF,0x00,0xFF,0x8A,0xAD,0x00,0xFF,0x8D,0xAC,0x06,0xFF,0x91,0xAE,0x00,0xFF, + 0x89,0xAD,0x03,0xFF,0x8E,0xA9,0x04,0xFF,0x91,0xB9,0x00,0xFF,0xA2,0xCB,0x05,0xFF,0x4E,0x82,0x5C,0xFF, + 0x13,0x37,0x5B,0xFF,0x00,0x46,0x8A,0xFF,0x00,0x51,0xAF,0xFF,0x04,0x53,0xAF,0xFF,0x03,0x51,0xA6,0xFF, + 0x03,0x4F,0xA7,0xFF,0x04,0x4D,0xA9,0xFF,0x03,0x53,0xAA,0xFF,0x01,0x54,0xB2,0xFF,0x00,0x53,0xB3,0xFF, + 0x00,0x56,0xB4,0xFF,0x00,0x5B,0xB7,0xFF,0x00,0x56,0xB8,0xFF,0x02,0x4F,0xB7,0xFF,0x02,0x51,0xB0,0xFF, + 0x00,0x53,0xA3,0xFF,0x00,0x57,0xA5,0xFF,0x02,0x51,0xAD,0xFF,0x00,0x54,0xB6,0xFF,0x00,0x4F,0xA9,0xFF, + 0x08,0x55,0xA7,0xFF,0x00,0x4C,0xAE,0xFF,0x00,0x55,0xB3,0xFF,0x00,0x55,0xA4,0xFF,0x04,0x56,0xAA,0xFF, + 0x00,0x50,0xAA,0xFF,0x00,0x56,0xAC,0xFF,0x05,0x58,0xB6,0xFF,0x00,0x53,0xAC,0xFF,0x07,0x52,0xAD,0xFF, + 0x00,0x6F,0xD5,0xFF,0x21,0x89,0xE2,0xFF,0x36,0x68,0x5F,0xFF,0x2F,0x40,0x14,0xFF,0x67,0x85,0x00,0xFF, + 0x84,0x9F,0x02,0xFF,0x90,0xAD,0x00,0xFF,0x88,0xB1,0x00,0xFF,0x8C,0xAA,0x00,0xFF,0x8E,0xAE,0x0F,0xFF, + 0x8D,0xAD,0x00,0xFF,0xA1,0xCB,0x07,0xFF,0x8D,0xB9,0x30,0xFF,0x10,0x3A,0x60,0xFF,0x05,0x38,0x79,0xFF, + 0x05,0x52,0xAA,0xFF,0x08,0x52,0xAB,0xFF,0x00,0x53,0xB1,0xFF,0x05,0x53,0xB5,0xFF,0x00,0x58,0xAC,0xFF, + 0x00,0x7B,0xFA,0xFF,0x28,0x7C,0xD2,0xFF,0x28,0x32,0x1A,0xFF,0x44,0x5B,0x03,0xFF,0x88,0xA2,0x01,0xFF, + 0x87,0xA9,0x00,0xFF,0x8A,0xAF,0x00,0xFF,0x8B,0xAD,0x01,0xFF,0x8D,0xA9,0x00,0xFF,0x87,0xAD,0x00,0xFF, + 0x8F,0xAC,0x00,0xFF,0x8E,0xB7,0x03,0xFF,0xA2,0xCC,0x20,0xFF,0x32,0x6C,0x60,0xFF,0x00,0x2A,0x5A,0xFF, + 0x00,0x4B,0x92,0xFF,0x02,0x53,0xAF,0xFF,0x02,0x50,0xB2,0xFF,0x03,0x52,0xB9,0xFF,0x00,0x52,0xB3,0xFF, + 0x00,0x56,0xAD,0xFF,0x00,0x50,0xA9,0xFF,0x00,0x4E,0xAA,0xFF,0x05,0x52,0xAC,0xFF,0x05,0x52,0xAC,0xFF, + 0x05,0x52,0xAC,0xFF,0x05,0x52,0xAC,0xFF,0x04,0x51,0xA9,0xFF,0x01,0x55,0xAB,0xFF,0x00,0x56,0xA7,0xFF, + 0x04,0x50,0xB0,0xFF,0x04,0x4C,0xB0,0xFF,0x08,0x53,0xAE,0xFF,0x02,0x51,0xAE,0xFF,0x00,0x4F,0xAB,0xFF, + 0x03,0x55,0xAB,0xFF,0x00,0x4E,0xAF,0xFF,0x03,0x4F,0xAF,0xFF,0x01,0x50,0xAC,0xFF,0x00,0x52,0xAA,0xFF, + 0x00,0x53,0xAD,0xFF,0x00,0x4F,0xA9,0xFF,0x00,0x59,0xA4,0xFF,0x01,0x4C,0xA9,0xFF,0x03,0x6F,0xCA,0xFF, + 0x13,0x7B,0xDE,0xFF,0x31,0x7E,0x9C,0xFF,0x3C,0x55,0x11,0xFF,0x51,0x6A,0x05,0xFF,0x88,0xA8,0x05,0xFF, + 0x8F,0xAD,0x00,0xFF,0x88,0xAF,0x00,0xFF,0x8B,0xAB,0x02,0xFF,0x8F,0xAD,0x00,0xFF,0x8B,0xB5,0x00,0xFF, + 0xAB,0xD8,0x03,0xFF,0x79,0xA6,0x41,0xFF,0x09,0x34,0x47,0xFF,0x00,0x37,0x7D,0xFF,0x00,0x4F,0xB2,0xFF, + 0x01,0x54,0xB0,0xFF,0x00,0x51,0xAC,0xFF,0x01,0x51,0xB4,0xFF,0x02,0x52,0xA9,0xFF,0x00,0x75,0xFB,0xFF, + 0x2A,0x7B,0xCC,0xFF,0x35,0x4C,0x2F,0xFF,0x38,0x49,0x03,0xFF,0x7E,0x9E,0x00,0xFF,0x8C,0xAC,0x00,0xFF, + 0x8E,0xAB,0x01,0xFF,0x91,0xA9,0x09,0xFF,0x8F,0xAC,0x02,0xFF,0x8A,0xAC,0x00,0xFF,0x8D,0xAF,0x03,0xFF, + 0xA2,0xCA,0x07,0xFF,0x96,0xBB,0x37,0xFF,0x23,0x54,0x74,0xFF,0x00,0x39,0x82,0xFF,0x01,0x4C,0x9F,0xFF, + 0x0A,0x4C,0xA3,0xFF,0x00,0x53,0xA4,0xFF,0x00,0x54,0xAE,0xFF,0x00,0x51,0xAA,0xFF,0x02,0x53,0xA5,0xFF, + 0x00,0x53,0xA9,0xFF,0x06,0x55,0xB1,0xFF,0x00,0x4E,0xAE,0xFF,0x00,0x52,0xB2,0xFF,0x03,0x52,0xAE,0xFF, + 0x00,0x51,0xA5,0xFF,0x00,0x55,0xA6,0xFF,0x00,0x53,0xAC,0xFF,0x04,0x53,0xB2,0xFF,0x02,0x53,0xAE,0xFF, + 0x00,0x52,0xA7,0xFF,0x03,0x52,0xB7,0xFF,0x00,0x52,0xA8,0xFF,0x00,0x55,0xAE,0xFF,0x01,0x54,0xA4,0xFF, + 0x03,0x50,0xAC,0xFF,0x00,0x55,0xB0,0xFF,0x01,0x50,0xB5,0xFF,0x00,0x54,0xA5,0xFF,0x07,0x52,0xAF,0xFF, + 0x02,0x4D,0xB3,0xFF,0x04,0x53,0xB0,0xFF,0x04,0x4E,0xAD,0xFF,0x00,0x5A,0xB8,0xFF,0x06,0x73,0xD2,0xFF, + 0x1E,0x7C,0xBA,0xFF,0x35,0x4F,0x22,0xFF,0x47,0x5F,0x00,0xFF,0x78,0x9A,0x00,0xFF,0x8F,0xA8,0x04,0xFF, + 0x8A,0xB1,0x00,0xFF,0x8B,0xAC,0x00,0xFF,0x90,0xAB,0x04,0xFF,0x95,0xB2,0x02,0xFF,0xC1,0xEE,0x00,0xFF, + 0x77,0xA7,0x44,0xFF,0x05,0x21,0x2D,0xFF,0x00,0x35,0x62,0xFF,0x02,0x4F,0xA9,0xFF,0x00,0x57,0xA7,0xFF, + 0x05,0x4E,0xAA,0xFF,0x00,0x4F,0xAB,0xFF,0x00,0x57,0xA6,0xFF,0x00,0x68,0xE3,0xFF,0x34,0x81,0xD3,0xFF, + 0x3A,0x4C,0x34,0xFF,0x32,0x4C,0x0B,0xFF,0x75,0x91,0x00,0xFF,0x8F,0xAD,0x00,0xFF,0x89,0xB0,0x00,0xFF, + 0x8C,0xA9,0x00,0xFF,0x87,0xAF,0x00,0xFF,0x8F,0xAB,0x00,0xFF,0x87,0xB2,0x00,0xFF,0xAF,0xD9,0x09,0xFF, + 0x6B,0x95,0x43,0xFF,0x06,0x40,0x65,0xFF,0x01,0x49,0x9B,0xFF,0x00,0x53,0xA7,0xFF,0x05,0x4F,0xAE,0xFF, + 0x00,0x59,0xAF,0xFF,0x03,0x4F,0xA7,0xFF,0x05,0x51,0xAF,0xFF,0x01,0x51,0xB2,0xFF,0x02,0x51,0xB0,0xFF, + 0x00,0x53,0xA8,0xFF,0x05,0x51,0xB1,0xFF,0x04,0x4E,0xAF,0xFF,0x01,0x52,0xAB,0xFF,0x00,0x56,0xAA,0xFF, + 0x00,0x52,0xB0,0xFF,0x04,0x50,0xB2,0xFF,0x05,0x50,0xAD,0xFF,0x00,0x51,0xA9,0xFF,0x07,0x53,0xAB,0xFF, + 0x00,0x52,0xA6,0xFF,0x00,0x53,0xB4,0xFF,0x01,0x4F,0xB1,0xFF,0x05,0x53,0xA8,0xFF,0x00,0x54,0xAF,0xFF, + 0x00,0x52,0xB2,0xFF,0x00,0x50,0xB0,0xFF,0x03,0x52,0xAE,0xFF,0x04,0x4F,0xAC,0xFF,0x00,0x54,0xAE,0xFF, + 0x00,0x53,0xAD,0xFF,0x02,0x51,0xB6,0xFF,0x00,0x5A,0xB7,0xFF,0x0C,0x67,0xAD,0xFF,0x13,0x75,0xD6,0xFF, + 0x32,0x58,0x4B,0xFF,0x3C,0x47,0x03,0xFF,0x78,0x9D,0x00,0xFF,0x8B,0xAC,0x05,0xFF,0x8E,0xAA,0x00,0xFF, + 0x8A,0xAC,0x00,0xFF,0x8E,0xAF,0x06,0xFF,0x93,0xB4,0x01,0xFF,0xB7,0xDC,0x00,0xFF,0xAC,0xDB,0x3D,0xFF, + 0x20,0x46,0x39,0xFF,0x00,0x25,0x45,0xFF,0x04,0x3E,0x90,0xFF,0x01,0x53,0xA5,0xFF,0x03,0x51,0xB6,0xFF, + 0x03,0x50,0xAC,0xFF,0x02,0x57,0xA8,0xFF,0x01,0x68,0xDF,0xFF,0x29,0x87,0xCF,0xFF,0x44,0x63,0x44,0xFF, + 0x4F,0x59,0x12,0xFF,0x79,0x9B,0x00,0xFF,0x91,0xAE,0x04,0xFF,0x8B,0xAC,0x00,0xFF,0x8B,0xAD,0x00,0xFF, + 0x88,0xAF,0x00,0xFF,0x90,0xAD,0x05,0xFF,0x99,0xAF,0x02,0xFF,0xAF,0xE2,0x0B,0xFF,0x2E,0x5E,0x46,0xFF, + 0x00,0x29,0x5A,0xFF,0x00,0x53,0xA6,0xFF,0x02,0x51,0xBA,0xFF,0x00,0x54,0xAF,0xFF,0x00,0x51,0xAC,0xFF, + 0x05,0x51,0xAF,0xFF,0x00,0x53,0xAB,0xFF,0x00,0x54,0xAC,0xFF,0x04,0x50,0xAE,0xFF,0x04,0x4E,0xAD,0xFF, + 0x04,0x51,0xAB,0xFF,0x00,0x4F,0xAC,0xFF,0x00,0x56,0xAF,0xFF,0x02,0x4F,0xBB,0xFF,0x00,0x59,0xA9,0xFF, + 0x06,0x52,0xAA,0xFF,0x04,0x50,0xB2,0xFF,0x00,0x51,0xAC,0xFF,0x00,0x52,0xAC,0xFF,0x03,0x55,0xA9,0xFF, + 0x00,0x53,0xA3,0xFF,0x01,0x51,0xAA,0xFF,0x04,0x50,0xB0,0xFF,0x00,0x53,0xAA,0xFF,0x00,0x51,0xA3,0xFF, + 0x00,0x53,0xAF,0xFF,0x00,0x52,0xA9,0xFF,0x04,0x4D,0xA9,0xFF,0x00,0x50,0xAC,0xFF,0x00,0x54,0xAE,0xFF, + 0x02,0x5C,0xBC,0xFF,0x0A,0x60,0xB7,0xFF,0x0E,0x59,0x92,0xFF,0x00,0x77,0xD3,0xFF,0x2B,0x64,0x5E,0xFF, + 0x29,0x37,0x02,0xFF,0x73,0x93,0x02,0xFF,0x8D,0xAD,0x02,0xFF,0x91,0xAD,0x01,0xFF,0x88,0xAD,0x00,0xFF, + 0x8B,0xAE,0x00,0xFF,0x91,0xAD,0x01,0xFF,0xA3,0xCC,0x02,0xFF,0xD1,0xFD,0x20,0xFF,0x70,0x99,0x57,0xFF, + 0x0B,0x21,0x1E,0xFF,0x00,0x27,0x48,0xFF,0x00,0x31,0x59,0xFF,0x04,0x3F,0x8F,0xFF,0x00,0x48,0x9F,0xFF, + 0x00,0x52,0xA1,0xFF,0x04,0x5B,0xBC,0xFF,0x08,0x6A,0xC5,0xFF,0x43,0x59,0x44,0xFF,0x52,0x76,0x0A,0xFF, + 0x86,0xA3,0x00,0xFF,0x85,0xAB,0x00,0xFF,0x8F,0xAC,0x02,0xFF,0x8F,0xAD,0x00,0xFF,0x8A,0xA9,0x03,0xFF, + 0x89,0xB1,0x00,0xFF,0x95,0xC0,0x11,0xFF,0x91,0xBA,0x36,0xFF,0x20,0x41,0x50,0xFF,0x08,0x33,0x81,0xFF, + 0x04,0x56,0xAC,0xFF,0x05,0x4D,0xA1,0xFF,0x04,0x4F,0xAA,0xFF,0x05,0x55,0xAA,0xFF,0x02,0x4A,0x9F,0xFF, + 0x00,0x46,0x8B,0xFF,0x03,0x4E,0x92,0xFF,0x00,0x42,0x89,0xFF,0x00,0x46,0x8B,0xFF,0x00,0x4E,0x9D,0xFF, + 0x01,0x52,0xAB,0xFF,0x0B,0x52,0xAE,0xFF,0x02,0x52,0xB1,0xFF,0x00,0x4A,0xA2,0xFF,0x01,0x51,0xA6,0xFF, + 0x00,0x54,0xAA,0xFF,0x05,0x55,0xB4,0xFF,0x00,0x51,0xAE,0xFF,0x00,0x50,0xAE,0xFF,0x00,0x50,0xA9,0xFF, + 0x07,0x53,0xAB,0xFF,0x01,0x51,0xAA,0xFF,0x00,0x52,0xAA,0xFF,0x0A,0x45,0xA1,0xFF,0x02,0x37,0x87,0xFF, + 0x00,0x37,0x5C,0xFF,0x07,0x39,0x78,0xFF,0x04,0x3C,0x86,0xFF,0x03,0x4E,0x88,0xFF,0x02,0x56,0xB0,0xFF, + 0x0D,0x64,0xC5,0xFF,0x0D,0x4E,0x8E,0xFF,0x01,0x77,0xD7,0xFF,0x31,0x6B,0x5D,0xFF,0x35,0x48,0x06,0xFF, + 0x7D,0x99,0x08,0xFF,0x8D,0xAE,0x00,0xFF,0x8E,0xAC,0x00,0xFF,0x8D,0xAF,0x03,0xFF,0x8A,0xAB,0x00,0xFF, + 0x87,0xAD,0x00,0xFF,0x93,0xB4,0x03,0xFF,0xB7,0xE9,0x0C,0xFF,0xDA,0xFF,0x2C,0xFF,0x6B,0x91,0x6C,0xFF, + 0x1A,0x2C,0x3A,0xFF,0x00,0x17,0x26,0xFF,0x00,0x10,0x22,0xFF,0x00,0x13,0x2E,0xFF,0x00,0x1C,0x34,0xFF, + 0x01,0x26,0x5A,0xFF,0x04,0x34,0x64,0xFF,0x45,0x52,0x26,0xFF,0x71,0x92,0x00,0xFF,0x94,0xB2,0x02,0xFF, + 0x88,0xAF,0x00,0xFF,0x8C,0xA9,0x03,0xFF,0x86,0xAD,0x00,0xFF,0x90,0xB4,0x00,0xFF,0x91,0xB4,0x00,0xFF, + 0xAB,0xD4,0x14,0xFF,0x7B,0x94,0x5D,0xFF,0x08,0x27,0x44,0xFF,0x00,0x39,0x78,0xFF,0x03,0x52,0xB1,0xFF, + 0x00,0x50,0xAC,0xFF,0x04,0x55,0xAE,0xFF,0x00,0x41,0x7C,0xFF,0x00,0x25,0x40,0xFF,0x05,0x1F,0x52,0xFF, + 0x04,0x20,0x45,0xFF,0x00,0x19,0x30,0xFF,0x00,0x0C,0x13,0xFF,0x00,0x1D,0x44,0xFF,0x00,0x50,0x84,0xFF, + 0x00,0x4C,0xAE,0xFF,0x00,0x53,0xA3,0xFF,0x00,0x59,0xAD,0xFF,0x00,0x57,0xB7,0xFF,0x03,0x4F,0xAD,0xFF, + 0x00,0x4F,0xA2,0xFF,0x08,0x54,0xB6,0xFF,0x00,0x55,0xB2,0xFF,0x00,0x52,0xA8,0xFF,0x05,0x52,0xAA,0xFF, + 0x00,0x50,0xAB,0xFF,0x00,0x47,0x8C,0xFF,0x01,0x2C,0x3F,0xFF,0x00,0x10,0x1A,0xFF,0x04,0x09,0x0D,0xFF, + 0x00,0x03,0x14,0xFF,0x00,0x0E,0x1D,0xFF,0x00,0x1A,0x36,0xFF,0x00,0x42,0x8D,0xFF,0x05,0x6C,0xC8,0xFF, + 0x08,0x53,0x97,0xFF,0x0B,0x4D,0x9B,0xFF,0x3D,0x64,0x2F,0xFF,0x62,0x75,0x02,0xFF,0x85,0xA4,0x01,0xFF, + 0x8B,0xAD,0x00,0xFF,0x89,0xA9,0x00,0xFF,0x8D,0xAD,0x02,0xFF,0x90,0xAC,0x00,0xFF,0x94,0xAB,0x03,0xFF, + 0x88,0xB1,0x00,0xFF,0x97,0xB3,0x00,0xFF,0xBA,0xE8,0x00,0xFF,0xDA,0xFE,0x2A,0xFF,0xB1,0xD9,0x52,0xFF, + 0x78,0x91,0x58,0xFF,0x2F,0x5B,0x44,0xFF,0x24,0x3F,0x38,0xFF,0x18,0x36,0x38,0xFF,0x21,0x49,0x4B,0xFF, + 0x4E,0x6F,0x40,0xFF,0x74,0xA0,0x05,0xFF,0x8A,0xA5,0x00,0xFF,0x8C,0xA8,0x00,0xFF,0x8F,0xA9,0x0A,0xFF, + 0x8B,0xAC,0x03,0xFF,0x8C,0xAD,0x06,0xFF,0x8D,0xA7,0x00,0xFF,0x9C,0xBA,0x00,0xFF,0xB2,0xE9,0x1E,0xFF, + 0x6A,0x9C,0x5D,0xFF,0x00,0x29,0x28,0xFF,0x05,0x25,0x5E,0xFF,0x00,0x42,0x88,0xFF,0x00,0x4C,0x97,0xFF, + 0x00,0x36,0x81,0xFF,0x21,0x45,0x55,0xFF,0x32,0x4A,0x3A,0xFF,0x3C,0x64,0x49,0xFF,0x40,0x6E,0x54,0xFF, + 0x4D,0x73,0x4C,0xFF,0x06,0x07,0x0B,0xFF,0x00,0x01,0x02,0xFF,0x05,0x21,0x49,0xFF,0x00,0x47,0x93,0xFF, + 0x04,0x54,0xA9,0xFF,0x05,0x4F,0xA6,0xFF,0x00,0x4F,0xAE,0xFF,0x00,0x51,0xAF,0xFF,0x00,0x52,0xAA,0xFF, + 0x07,0x51,0xAA,0xFF,0x00,0x51,0xA8,0xFF,0x00,0x51,0xA7,0xFF,0x00,0x58,0xB9,0xFF,0x01,0x5C,0xAD,0xFF, + 0x14,0x40,0x67,0xFF,0x1C,0x2F,0x3D,0xFF,0x39,0x5A,0x2D,0xFF,0x5D,0x85,0x49,0xFF,0x49,0x76,0x4B,0xFF, + 0x2B,0x4A,0x4C,0xFF,0x00,0x07,0x0E,0xFF,0x00,0x23,0x3D,0xFF,0x05,0x57,0xA0,0xFF,0x0A,0x59,0x92,0xFF, + 0x23,0x41,0x39,0xFF,0x5C,0x77,0x04,0xFF,0x86,0x9F,0x03,0xFF,0x88,0xAB,0x00,0xFF,0x8E,0xAF,0x00,0xFF, + 0x8D,0xAA,0x00,0xFF,0x8A,0xAA,0x01,0xFF,0x8E,0xAE,0x01,0xFF,0x8A,0xAB,0x06,0xFF,0x89,0xAF,0x00,0xFF, + 0x8C,0xAE,0x02,0xFF,0x96,0xB4,0x06,0xFF,0xA4,0xDC,0x00,0xFF,0xD0,0xFF,0x07,0xFF,0xD2,0xFC,0x16,0xFF, + 0xDC,0xFE,0x35,0xFF,0xDA,0xFB,0x38,0xFF,0xD0,0xFF,0x21,0xFF,0xB9,0xE1,0x1E,0xFF,0x9B,0xC6,0x14,0xFF, + 0x8E,0xB5,0x00,0xFF,0x88,0xAD,0x07,0xFF,0x8E,0xAD,0x00,0xFF,0x8B,0xAF,0x03,0xFF,0x89,0xAD,0x03,0xFF, + 0x8F,0xAB,0x01,0xFF,0x91,0xAE,0x00,0xFF,0x9A,0xBC,0x03,0xFF,0xBA,0xF0,0x16,0xFF,0xA8,0xE8,0x4B,0xFF, + 0x1F,0x46,0x57,0xFF,0x04,0x1C,0x38,0xFF,0x00,0x1D,0x45,0xFF,0x06,0x3B,0x7F,0xFF,0x2D,0x70,0x76,0xFF, + 0x69,0x9F,0x41,0xFF,0xB6,0xE3,0x28,0xFF,0xC2,0xEF,0x22,0xFF,0xCC,0xFB,0x23,0xFF,0xD5,0xFF,0x19,0xFF, + 0xCB,0xE6,0x39,0xFF,0x2B,0x45,0x2C,0xFF,0x00,0x01,0x00,0xFF,0x07,0x1D,0x44,0xFF,0x00,0x47,0x92,0xFF, + 0x02,0x51,0xB6,0xFF,0x01,0x55,0xAB,0xFF,0x03,0x52,0xB1,0xFF,0x02,0x52,0xAB,0xFF,0x00,0x4F,0xAC,0xFF, + 0x00,0x53,0xB1,0xFF,0x01,0x56,0xA7,0xFF,0x00,0x61,0xCC,0xFF,0x1B,0x64,0xA9,0xFF,0x41,0x58,0x20,0xFF, + 0x5F,0x7E,0x07,0xFF,0x8D,0xB3,0x00,0xFF,0xBD,0xEF,0x02,0xFF,0xD0,0xFD,0x0C,0xFF,0xD0,0xFF,0x1C,0xFF, + 0x88,0xBD,0x2D,0xFF,0x18,0x49,0x74,0xFF,0x02,0x44,0x98,0xFF,0x4A,0x9C,0x6B,0xFF,0x6C,0x8C,0x11,0xFF, + 0x80,0xA3,0x00,0xFF,0x8B,0xAF,0x05,0xFF,0x8D,0xB0,0x00,0xFF,0x8E,0xAD,0x00,0xFF,0x90,0xAB,0x04,0xFF, + 0x8C,0xAC,0x01,0xFF,0x87,0xAE,0x00,0xFF,0x90,0xAC,0x00,0xFF,0x8B,0xAD,0x00,0xFF,0x8A,0xAC,0x00,0xFF, + 0x91,0xAA,0x06,0xFF,0x8D,0xA7,0x00,0xFF,0x97,0xB4,0x00,0xFF,0x9B,0xBD,0x04,0xFF,0xA1,0xCF,0x0D,0xFF, + 0xA9,0xCE,0x02,0xFF,0xA4,0xD0,0x01,0xFF,0x96,0xB3,0x03,0xFF,0x89,0xB1,0x00,0xFF,0x8D,0xAB,0x00,0xFF, + 0x89,0xAF,0x02,0xFF,0x90,0xAB,0x06,0xFF,0x89,0xAB,0x00,0xFF,0x8C,0xB1,0x01,0xFF,0x8F,0xAB,0x00,0xFF, + 0x8A,0xAC,0x00,0xFF,0x90,0xBA,0x01,0xFF,0xAD,0xD0,0x02,0xFF,0xD5,0xFF,0x11,0xFF,0xB2,0xE6,0x46,0xFF, + 0x6C,0x99,0x5E,0xFF,0x57,0x73,0x4B,0xFF,0x70,0x96,0x41,0xFF,0xA8,0xCE,0x2B,0xFF,0xA9,0xCA,0x00,0xFF, + 0x9C,0xB9,0x00,0xFF,0x9E,0xBB,0x00,0xFF,0x99,0xB8,0x00,0xFF,0xB6,0xDD,0x06,0xFF,0xD4,0xFD,0x01,0xFF, + 0xC2,0xE6,0x3C,0xFF,0x07,0x22,0x35,0xFF,0x06,0x0F,0x36,0xFF,0x00,0x44,0x8A,0xFF,0x00,0x52,0xA8,0xFF, + 0x05,0x50,0xAB,0xFF,0x00,0x53,0xB0,0xFF,0x02,0x53,0xAE,0xFF,0x01,0x51,0xB2,0xFF,0x00,0x4E,0xB0,0xFF, + 0x00,0x5A,0xBB,0xFF,0x19,0x79,0xCF,0xFF,0x49,0x76,0x7B,0xFF,0x5A,0x6C,0x00,0xFF,0x70,0x93,0x00,0xFF, + 0x8E,0xB3,0x03,0xFF,0x8A,0xB4,0x00,0xFF,0xA1,0xB9,0x09,0xFF,0xB9,0xDE,0x00,0xFF,0xC4,0xF4,0x00,0xFF, + 0xB3,0xDE,0x13,0xFF,0xA7,0xD3,0x0A,0xFF,0xAD,0xD4,0x00,0xFF,0x9B,0xBE,0x0A,0xFF,0x8B,0xB2,0x00,0xFF, + 0x87,0xAB,0x01,0xFF,0x8E,0xAE,0x01,0xFF,0x8A,0xA8,0x00,0xFF,0x8D,0xAD,0x04,0xFF,0x8E,0xB0,0x01,0xFF, + 0x89,0xAE,0x00,0xFF,0x8A,0xAE,0x02,0xFF,0x8A,0xAA,0x00,0xFF,0x91,0xAE,0x08,0xFF,0x8A,0xAF,0x00,0xFF, + 0x8F,0xAC,0x06,0xFF,0x8B,0xAB,0x00,0xFF,0x8E,0xA8,0x00,0xFF,0x97,0xA8,0x02,0xFF,0x87,0xAC,0x00,0xFF, + 0x8E,0xAB,0x05,0xFF,0x89,0xA9,0x00,0xFF,0x92,0xAB,0x0F,0xFF,0x8F,0xAD,0x00,0xFF,0x8A,0xA6,0x00,0xFF, + 0x8D,0xAA,0x02,0xFF,0x94,0xAF,0x02,0xFF,0x8B,0xA8,0x00,0xFF,0x92,0xAB,0x09,0xFF,0x8E,0xAC,0x00,0xFF, + 0x82,0xAA,0x00,0xFF,0x90,0xBB,0x00,0xFF,0xA3,0xCD,0x00,0xFF,0xCB,0xF8,0x05,0xFF,0xD1,0xFF,0x14,0xFF, + 0xBE,0xEA,0x11,0xFF,0xA0,0xCB,0x09,0xFF,0x8F,0xB5,0x00,0xFF,0x8F,0xAD,0x00,0xFF,0x8E,0xAF,0x00,0xFF, + 0x93,0xAF,0x03,0xFF,0x8F,0xAD,0x00,0xFF,0x86,0xB6,0x00,0xFF,0xB1,0xE2,0x00,0xFF,0xCC,0xFF,0x04,0xFF, + 0x41,0x87,0x51,0xFF,0x00,0x07,0x11,0xFF,0x02,0x30,0x61,0xFF,0x00,0x54,0xAA,0xFF,0x04,0x4E,0xAD,0xFF, + 0x02,0x52,0xA7,0xFF,0x00,0x54,0xA4,0xFF,0x04,0x52,0xB4,0xFF,0x01,0x51,0xA6,0xFF,0x00,0x73,0xCC,0xFF, + 0x33,0x8A,0xB7,0xFF,0x4A,0x61,0x2B,0xFF,0x51,0x69,0x00,0xFF,0x82,0xA7,0x02,0xFF,0x8B,0xB2,0x00,0xFF, + 0x8C,0xAF,0x0A,0xFF,0x8B,0xAD,0x00,0xFF,0x8B,0xB3,0x03,0xFF,0x93,0xB7,0x00,0xFF,0xAB,0xCD,0x00,0xFF, + 0x93,0xBD,0x00,0xFF,0x94,0xB5,0x02,0xFF,0x92,0xAB,0x00,0xFF,0x89,0xAA,0x00,0xFF,0x8E,0xAE,0x01,0xFF, + 0x8E,0xAB,0x01,0xFF,0x8B,0xAD,0x01,0xFF,0x8C,0xB0,0x06,0xFF,0x89,0xAA,0x00,0xFF,0x8F,0xAA,0x03,0xFF, + 0x8C,0xAB,0x05,0xFF,0x91,0xAC,0x00,0xFF,0x89,0xAB,0x00,0xFF,0x89,0xAE,0x00,0xFF,0x8E,0xAB,0x01,0xFF, + 0x8C,0xAD,0x00,0xFF,0x88,0xB3,0x02,0xFF,0x88,0xAD,0x00,0xFF,0x89,0xAF,0x00,0xFF,0x8E,0xAD,0x00,0xFF, + 0x8C,0xAE,0x02,0xFF,0x8A,0xAA,0x00,0xFF,0x8D,0xAE,0x00,0xFF,0x8D,0xAF,0x00,0xFF,0x8A,0xB1,0x06,0xFF, + 0x88,0xAA,0x00,0xFF,0x92,0xAD,0x00,0xFF,0x87,0xAD,0x00,0xFF,0x8D,0xAF,0x00,0xFF,0x95,0xAB,0x0A,0xFF, + 0x8C,0xAB,0x00,0xFF,0x8B,0xAA,0x06,0xFF,0x94,0xB1,0x00,0xFF,0x9D,0xC1,0x00,0xFF,0x93,0xB4,0x01,0xFF, + 0x8C,0xB7,0x00,0xFF,0x8D,0xAE,0x05,0xFF,0x8F,0xAB,0x01,0xFF,0x86,0xAD,0x00,0xFF,0x87,0xAD,0x02,0xFF, + 0x8D,0xAA,0x00,0xFF,0x8E,0xAF,0x00,0xFF,0x92,0xB3,0x00,0xFF,0xD0,0xFE,0x05,0xFF,0x7F,0xA1,0x40,0xFF, + 0x04,0x09,0x0F,0xFF,0x00,0x33,0x60,0xFF,0x02,0x56,0xB8,0xFF,0x00,0x50,0xA9,0xFF,0x04,0x58,0xBA,0xFF, + 0x00,0x52,0xAE,0xFF,0x03,0x53,0xAC,0xFF,0x03,0x51,0xB5,0xFF,0x01,0x77,0xF5,0xFF,0x40,0x99,0xBB,0xFF, + 0x33,0x3E,0x1E,0xFF,0x41,0x55,0x00,0xFF,0x7C,0x9B,0x02,0xFF,0x8C,0xAF,0x00,0xFF,0x91,0xAB,0x02,0xFF, + 0x86,0xAC,0x00,0xFF,0x95,0xAA,0x03,0xFF,0x82,0xAF,0x00,0xFF,0x8D,0xAE,0x00,0xFF,0x8A,0xAB,0x00,0xFF, + 0x8C,0xAC,0x00,0xFF,0x8E,0xAB,0x03,0xFF,0x89,0xB1,0x01,0xFF,0x8E,0xA9,0x00,0xFF,0x8E,0xAF,0x06,0xFF, + 0x8B,0xAC,0x00,0xFF,0x93,0xAA,0x04,0xFF,0x84,0xAF,0x00,0xFF,0x8D,0xAA,0x04,0xFF,0x8D,0xAE,0x00,0xFF, + 0x8D,0xAE,0x00,0xFF,0x8D,0xA8,0x01,0xFF,0x8E,0xA8,0x06,0xFF,0x8A,0xB0,0x03,0xFF,0x92,0xA9,0x01,0xFF, + 0x84,0xB0,0x00,0xFF,0x8A,0xAC,0x00,0xFF,0x8B,0xAA,0x04,0xFF,0x8B,0xB1,0x06,0xFF,0x86,0xAC,0x01,0xFF, + 0x8E,0xAD,0x00,0xFF,0x8F,0xAA,0x03,0xFF,0x86,0xAA,0x02,0xFF,0x8C,0xAF,0x00,0xFF,0x92,0xAA,0x00,0xFF, + 0x87,0xAD,0x00,0xFF,0x8F,0xAB,0x01,0xFF,0x92,0xAD,0x00,0xFF,0x89,0xAE,0x00,0xFF,0x87,0xAC,0x06,0xFF, + 0x94,0xA7,0x00,0xFF,0x8D,0xA6,0x00,0xFF,0x72,0x91,0x07,0xFF,0x5C,0x74,0x00,0xFF,0x5D,0x6F,0x03,0xFF, + 0x70,0x96,0x05,0xFF,0x89,0xB1,0x00,0xFF,0x8E,0xAB,0x03,0xFF,0x8F,0xAC,0x04,0xFF,0x8D,0xA8,0x00,0xFF, + 0x88,0xAF,0x00,0xFF,0x8F,0xB3,0x00,0xFF,0xBC,0xF0,0x07,0xFF,0x7F,0x99,0x36,0xFF,0x00,0x10,0x1F,0xFF, + 0x00,0x32,0x5F,0xFF,0x07,0x53,0xB5,0xFF,0x00,0x51,0xAB,0xFF,0x00,0x57,0xB8,0xFF,0x00,0x50,0xA5,0xFF, + 0x00,0x53,0xAE,0xFF,0x00,0x50,0xA5,0xFF,0x02,0x7C,0xFB,0xFF,0x3C,0x95,0xB3,0xFF,0x2C,0x31,0x00,0xFF, + 0x40,0x54,0x00,0xFF,0x74,0x90,0x07,0xFF,0x8A,0xAA,0x00,0xFF,0x8F,0xA8,0x04,0xFF,0x8E,0xAA,0x00,0xFF, + 0x89,0xAF,0x00,0xFF,0x8C,0xAD,0x04,0xFF,0x90,0xA6,0x00,0xFF,0x8A,0xB3,0x0C,0xFF,0x8D,0xAB,0x00,0xFF, + 0x90,0xAC,0x02,0xFF,0x84,0xAB,0x00,0xFF,0x91,0xB0,0x00,0xFF,0x8D,0xAC,0x00,0xFF,0x87,0xA9,0x00,0xFF, + 0x8C,0xAE,0x02,0xFF,0x8D,0xAE,0x07,0xFF,0x8F,0xAC,0x00,0xFF,0x8E,0xAC,0x00,0xFF,0x8B,0xAA,0x04,0xFF, + 0x8E,0xAD,0x00,0xFF,0x8F,0xAC,0x02,0xFF,0x86,0xB0,0x00,0xFF,0x90,0xA7,0x01,0xFF,0x8C,0xB1,0x01,0xFF, + 0x91,0xAC,0x00,0xFF,0x8E,0xAC,0x00,0xFF,0x8F,0xA6,0x00,0xFF,0x91,0xAE,0x00,0xFF,0x8B,0xAD,0x00,0xFF, + 0x8A,0xAC,0x00,0xFF,0x8C,0xAE,0x00,0xFF,0x89,0xAD,0x03,0xFF,0x8D,0xAB,0x00,0xFF,0x8C,0xAD,0x00,0xFF, + 0x8D,0xA9,0x00,0xFF,0x8F,0xA9,0x00,0xFF,0x8D,0xAD,0x02,0xFF,0x86,0xB2,0x00,0xFF,0x7D,0xA7,0x00,0xFF, + 0x59,0x72,0x17,0xFF,0x34,0x3F,0x15,0xFF,0x14,0x17,0x02,0xFF,0x00,0x02,0x07,0xFF,0x2B,0x30,0x00,0xFF, + 0x6A,0x7D,0x00,0xFF,0x84,0xA8,0x00,0xFF,0x8A,0xB3,0x01,0xFF,0x8C,0xAE,0x02,0xFF,0x91,0xAC,0x05,0xFF, + 0x92,0xB6,0x00,0xFF,0xB2,0xE3,0x15,0xFF,0x47,0x5F,0x47,0xFF,0x02,0x22,0x39,0xFF,0x02,0x40,0x89,0xFF, + 0x00,0x50,0xA1,0xFF,0x02,0x56,0xB0,0xFF,0x03,0x53,0xAA,0xFF,0x07,0x51,0xB0,0xFF,0x01,0x52,0xAD,0xFF, + 0x03,0x51,0xA6,0xFF,0x00,0x7B,0xFF,0xFF,0x2A,0x92,0xC7,0xFF,0x22,0x2A,0x13,0xFF,0x1D,0x29,0x00,0xFF, + 0x6E,0x86,0x00,0xFF,0x8B,0xB3,0x03,0xFF,0x87,0xAD,0x00,0xFF,0x8D,0xAE,0x00,0xFF,0x8F,0xAB,0x01,0xFF, + 0x8D,0xAA,0x00,0xFF,0x8B,0xB1,0x02,0xFF,0x81,0xA2,0x00,0xFF,0x7A,0x9B,0x06,0xFF,0x78,0x92,0x00,0xFF, + 0x6F,0x85,0x00,0xFF,0x72,0x8F,0x01,0xFF,0x82,0xA4,0x00,0xFF,0x91,0xAD,0x0B,0xFF,0x91,0xAD,0x00,0xFF, + 0x8F,0xAC,0x00,0xFF,0x88,0xAB,0x00,0xFF,0x88,0xAC,0x02,0xFF,0x8E,0xB1,0x00,0xFF,0x8D,0xAA,0x00,0xFF, + 0x92,0xAD,0x00,0xFF,0x8E,0xAF,0x00,0xFF,0x87,0xA0,0x07,0xFF,0x76,0x9D,0x00,0xFF,0x7C,0x9B,0x02,0xFF, + 0x75,0xA3,0x00,0xFF,0x83,0xA2,0x00,0xFF,0x90,0xAC,0x00,0xFF,0x8C,0xAA,0x0A,0xFF,0x8B,0xAE,0x00,0xFF, + 0x8A,0xB0,0x05,0xFF,0x89,0xAB,0x00,0xFF,0x93,0xA7,0x07,0xFF,0x91,0xAC,0x05,0xFF,0x8E,0xB0,0x00,0xFF, + 0x8A,0xAD,0x09,0xFF,0x88,0xA7,0x01,0xFF,0x93,0xB6,0x00,0xFF,0x6F,0x9A,0x2F,0xFF,0x3B,0x72,0x52,0xFF, + 0x1D,0x60,0x7A,0xFF,0x22,0x61,0x8A,0xFF,0x1D,0x43,0x56,0xFF,0x0C,0x1B,0x00,0xFF,0x28,0x37,0x0C,0xFF, + 0x47,0x58,0x00,0xFF,0x6E,0x83,0x00,0xFF,0x75,0x9C,0x01,0xFF,0x79,0x96,0x00,0xFF,0x8B,0xAA,0x06,0xFF, + 0x80,0xA8,0x13,0xFF,0x18,0x34,0x37,0xFF,0x01,0x2C,0x4F,0xFF,0x03,0x48,0x93,0xFF,0x00,0x55,0xA7,0xFF, + 0x00,0x52,0xAE,0xFF,0x02,0x50,0xA5,0xFF,0x02,0x50,0xB2,0xFF,0x00,0x52,0xA6,0xFF,0x01,0x56,0xA9,0xFF, + 0x00,0x7A,0xED,0xFF,0x31,0x93,0xEE,0xFF,0x43,0x56,0x38,0xFF,0x0C,0x0F,0x04,0xFF,0x3E,0x4F,0x01,0xFF, + 0x7F,0x96,0x00,0xFF,0x81,0xA5,0x00,0xFF,0x88,0xB1,0x00,0xFF,0x95,0xA7,0x07,0xFF,0x90,0xAC,0x00,0xFF, + 0x7B,0x9C,0x07,0xFF,0x65,0x77,0x07,0xFF,0x63,0x7D,0x10,0xFF,0x35,0x5D,0x21,0xFF,0x43,0x55,0x17,0xFF, + 0x44,0x4F,0x0A,0xFF,0x67,0x84,0x04,0xFF,0x8F,0xAD,0x00,0xFF,0x8B,0xA6,0x00,0xFF,0x8A,0xAA,0x00,0xFF, + 0x8F,0xB2,0x00,0xFF,0x8D,0xA9,0x00,0xFF,0x8E,0xAE,0x03,0xFF,0x89,0xAA,0x01,0xFF,0x89,0xAC,0x00,0xFF, + 0x73,0x95,0x0D,0xFF,0x52,0x6C,0x07,0xFF,0x28,0x34,0x0E,0xFF,0x23,0x22,0x03,0xFF,0x26,0x25,0x07,0xFF, + 0x42,0x54,0x00,0xFF,0x5D,0x78,0x03,0xFF,0x7D,0x9D,0x00,0xFF,0x8F,0xAB,0x08,0xFF,0x91,0xA9,0x00,0xFF, + 0x91,0xAD,0x01,0xFF,0x88,0xAD,0x05,0xFF,0x89,0xAC,0x00,0xFF,0x8A,0xAC,0x00,0xFF,0x89,0xAF,0x04,0xFF, + 0x8D,0xB2,0x00,0xFF,0xAD,0xD0,0x00,0xFF,0x58,0x7E,0x4D,0xFF,0x19,0x5C,0x86,0xFF,0x00,0x6A,0xDF,0xFF, + 0x00,0x88,0xFD,0xFF,0x0E,0x8B,0xF7,0xFF,0x32,0x77,0xA0,0xFF,0x20,0x39,0x1C,0xFF,0x00,0x01,0x0E,0xFF, + 0x0E,0x17,0x02,0xFF,0x3A,0x49,0x12,0xFF,0x46,0x55,0x02,0xFF,0x50,0x5C,0x14,0xFF,0x30,0x48,0x28,0xFF, + 0x11,0x38,0x59,0xFF,0x08,0x40,0x8A,0xFF,0x01,0x4E,0x9E,0xFF,0x02,0x57,0xB1,0xFF,0x00,0x51,0xAF,0xFF, + 0x03,0x53,0xAA,0xFF,0x00,0x53,0xA8,0xFF,0x01,0x50,0xAC,0xFF,0x00,0x51,0x9F,0xFF,0x04,0x70,0xD5,0xFF, + 0x28,0x92,0xFF,0xFF,0x4B,0x90,0xC9,0xFF,0x2D,0x52,0x27,0xFF,0x24,0x2B,0x00,0xFF,0x3C,0x4B,0x08,0xFF, + 0x54,0x67,0x0B,0xFF,0x56,0x74,0x02,0xFF,0x5A,0x72,0x04,0xFF,0x65,0x86,0x04,0xFF,0x37,0x56,0x06,0xFF, + 0x19,0x59,0x7C,0xFF,0x32,0x7C,0x85,0xFF,0x16,0x59,0x90,0xFF,0x20,0x56,0x78,0xFF,0x26,0x33,0x17,0xFF, + 0x44,0x52,0x00,0xFF,0x80,0xA7,0x00,0xFF,0x8D,0xAE,0x07,0xFF,0x89,0xAC,0x08,0xFF,0x8F,0xAA,0x00,0xFF, + 0x8D,0xAE,0x00,0xFF,0x89,0xAA,0x03,0xFF,0x86,0xA6,0x05,0xFF,0x77,0x95,0x03,0xFF,0x53,0x6F,0x18,0xFF, + 0x45,0x6C,0x35,0xFF,0x2B,0x47,0x4B,0xFF,0x20,0x3A,0x1D,0xFF,0x10,0x13,0x00,0xFF,0x01,0x12,0x02,0xFF, + 0x15,0x1B,0x01,0xFF,0x4F,0x55,0x00,0xFF,0x7C,0x9B,0x02,0xFF,0x8A,0xAF,0x00,0xFF,0x8C,0xAA,0x00,0xFF, + 0x87,0xB0,0x00,0xFF,0x8C,0xAF,0x0A,0xFF,0x8E,0xAA,0x00,0xFF,0x8D,0xAB,0x00,0xFF,0x9A,0xC1,0x04,0xFF, + 0xA6,0xCC,0x27,0xFF,0x26,0x4F,0x7B,0xFF,0x04,0x3C,0x77,0xFF,0x00,0x56,0xB0,0xFF,0x00,0x6D,0xD2,0xFF, + 0x00,0x6F,0xEC,0xFF,0x0A,0x84,0xFF,0xFF,0x3A,0x96,0xD7,0xFF,0x49,0x73,0x4B,0xFF,0x18,0x22,0x0A,0xFF, + 0x0E,0x0F,0x00,0xFF,0x1B,0x1C,0x0C,0xFF,0x19,0x2F,0x3A,0xFF,0x01,0x26,0x52,0xFF,0x03,0x41,0x8A,0xFF, + 0x00,0x51,0xAD,0xFF,0x00,0x52,0xAD,0xFF,0x00,0x51,0xA3,0xFF,0x01,0x52,0xAE,0xFF,0x00,0x50,0xAE,0xFF, + 0x00,0x53,0xB3,0xFF,0x01,0x53,0xA7,0xFF,0x00,0x55,0xA8,0xFF,0x02,0x59,0xC2,0xFF,0x00,0x6F,0xF1,0xFF, + 0x11,0x93,0xF3,0xFF,0x38,0x93,0xE6,0xFF,0x47,0x89,0x87,0xFF,0x3D,0x61,0x31,0xFF,0x4E,0x5B,0x16,0xFF, + 0x3E,0x52,0x0B,0xFF,0x49,0x63,0x22,0xFF,0x54,0x90,0x76,0xFF,0x2E,0x6F,0x69,0xFF,0x05,0x61,0xC4,0xFF, + 0x0A,0x7B,0xD7,0xFF,0x0F,0x64,0xC1,0xFF,0x14,0x79,0xD3,0xFF,0x30,0x5D,0x48,0xFF,0x39,0x45,0x05,0xFF, + 0x70,0x96,0x05,0xFF,0x8B,0xAB,0x00,0xFF,0x8D,0xAD,0x00,0xFF,0x8B,0xAB,0x00,0xFF,0x8D,0xAD,0x04,0xFF, + 0x91,0xB8,0x00,0xFF,0x83,0xA7,0x11,0xFF,0x3F,0x60,0x35,0xFF,0x10,0x45,0x67,0xFF,0x11,0x74,0xCF,0xFF, + 0x0C,0x7F,0xFF,0xFF,0x06,0x87,0xFC,0xFF,0x2A,0x8C,0xE3,0xFF,0x47,0x93,0x91,0xFF,0x2E,0x4C,0x26,0xFF, + 0x18,0x1C,0x0D,0xFF,0x43,0x61,0x00,0xFF,0x7E,0xA0,0x03,0xFF,0x91,0xA8,0x02,0xFF,0x89,0xAC,0x00,0xFF, + 0x8D,0xAA,0x02,0xFF,0x8C,0xAC,0x00,0xFF,0x8E,0xAE,0x03,0xFF,0xAC,0xD7,0x01,0xFF,0x9B,0xC7,0x2C,0xFF, + 0x06,0x42,0x88,0xFF,0x01,0x3E,0x7F,0xFF,0x08,0x50,0xB4,0xFF,0x01,0x51,0xB4,0xFF,0x07,0x5A,0xC0,0xFF, + 0x02,0x6F,0xEE,0xFF,0x05,0x87,0xFF,0xFF,0x0C,0x8C,0xFA,0xFF,0x49,0xA8,0xDE,0xFF,0x4C,0x8D,0x91,0xFF, + 0x24,0x73,0x84,0xFF,0x10,0x59,0x9D,0xFF,0x02,0x4D,0x90,0xFF,0x00,0x50,0xA0,0xFF,0x00,0x56,0xA9,0xFF, + 0x06,0x53,0xAF,0xFF,0x07,0x50,0xAE,0xFF,0x02,0x58,0xAF,0xFF,0x00,0x59,0xBB,0xFF,0x03,0x53,0xB2,0xFF, + 0x00,0x50,0xAA,0xFF,0x00,0x51,0xA6,0xFF,0x04,0x52,0xA7,0xFF,0x00,0x5C,0xBB,0xFF,0x00,0x68,0xC4,0xFF, + 0x02,0x71,0xF6,0xFF,0x03,0x7D,0xFF,0xFF,0x08,0x85,0xFD,0xFF,0x0B,0x72,0xCE,0xFF,0x02,0x64,0xBD,0xFF, + 0x0A,0x65,0xB8,0xFF,0x02,0x72,0xFA,0xFF,0x00,0x6C,0xD9,0xFF,0x00,0x56,0xBA,0xFF,0x0B,0x66,0xC3,0xFF, + 0x09,0x61,0xB8,0xFF,0x18,0x7A,0xB9,0xFF,0x3B,0x6D,0x52,0xFF,0x4C,0x5C,0x1B,0xFF,0x77,0x9A,0x00,0xFF, + 0x90,0xAD,0x00,0xFF,0x90,0xAC,0x02,0xFF,0x85,0xAE,0x00,0xFF,0x8F,0xA8,0x02,0xFF,0xA8,0xD2,0x02,0xFF, + 0x98,0xC6,0x32,0xFF,0x27,0x4B,0x57,0xFF,0x00,0x34,0x77,0xFF,0x00,0x6A,0xC7,0xFF,0x00,0x6E,0xE4,0xFF, + 0x01,0x76,0xE0,0xFF,0x04,0x7A,0xF5,0xFF,0x00,0x85,0xFE,0xFF,0x28,0x93,0xF3,0xFF,0x2A,0x54,0x60,0xFF, + 0x29,0x2E,0x00,0xFF,0x58,0x70,0x00,0xFF,0x7E,0xA5,0x00,0xFF,0x98,0xAE,0x01,0xFF,0x93,0xAE,0x07,0xFF, + 0x8C,0xAD,0x06,0xFF,0x86,0xAC,0x00,0xFF,0xA7,0xD4,0x00,0xFF,0x9C,0xC2,0x1F,0xFF,0x01,0x46,0x67,0xFF, + 0x00,0x42,0x83,0xFF,0x00,0x56,0xAF,0xFF,0x02,0x50,0xB2,0xFF,0x06,0x54,0x9F,0xFF,0x00,0x58,0xAF,0xFF, + 0x00,0x67,0xC6,0xFF,0x03,0x74,0xEC,0xFF,0x02,0x7F,0xFF,0xFF,0x00,0x80,0xF8,0xFF,0x00,0x76,0xF1,0xFF, + 0x00,0x62,0xD1,0xFF,0x00,0x57,0xB6,0xFF,0x00,0x55,0xAF,0xFF,0x00,0x53,0xAD,0xFF,0x04,0x4D,0xA9,0xFF, + 0x05,0x4C,0xB4,0xFF,0x00,0x52,0xA9,0xFF,0x00,0x5C,0xB6,0xFF,0x00,0x4F,0xAE,0xFF,0x09,0x54,0xA5,0xFF, + 0x05,0x45,0x9F,0xFF,0x00,0x52,0xA6,0xFF,0x00,0x59,0xA6,0xFF,0x01,0x50,0xAF,0xFF,0x09,0x53,0xAC,0xFF, + 0x00,0x58,0xB0,0xFF,0x00,0x6E,0xCF,0xFF,0x00,0x6A,0xCF,0xFF,0x04,0x64,0xCA,0xFF,0x02,0x58,0xAF,0xFF, + 0x03,0x4F,0xB1,0xFF,0x00,0x52,0xB9,0xFF,0x00,0x5E,0xB2,0xFF,0x0B,0x57,0xAB,0xFF,0x01,0x5E,0xAC,0xFF, + 0x32,0x66,0x8B,0xFF,0x50,0x66,0x37,0xFF,0x70,0x87,0x15,0xFF,0x82,0xAA,0x00,0xFF,0x88,0xAD,0x00,0xFF, + 0x8D,0xAB,0x00,0xFF,0x8D,0xAC,0x08,0xFF,0x8F,0xAD,0x00,0xFF,0xAE,0xDD,0x01,0xFF,0xAA,0xD2,0x60,0xFF, + 0x25,0x49,0x49,0xFF,0x00,0x2A,0x54,0xFF,0x00,0x54,0xA8,0xFF,0x03,0x53,0xB6,0xFF,0x00,0x4F,0xAC,0xFF, + 0x04,0x53,0xBC,0xFF,0x00,0x69,0xCB,0xFF,0x03,0x85,0xFF,0xFF,0x34,0x90,0xF7,0xFF,0x29,0x49,0x22,0xFF, + 0x2B,0x2D,0x08,0xFF,0x7A,0x9E,0x00,0xFF,0x87,0xAB,0x03,0xFF,0x85,0xAA,0x00,0xFF,0x8F,0xB0,0x00,0xFF, + 0x8C,0xAF,0x00,0xFF,0xA4,0xCE,0x08,0xFF,0xA9,0xC9,0x28,0xFF,0x0B,0x3E,0x69,0xFF,0x05,0x38,0x77,0xFF, + 0x00,0x51,0xA9,0xFF,0x00,0x53,0xAD,0xFF,0x00,0x55,0xAE,0xFF,0x06,0x50,0xB1,0xFF,0x02,0x51,0xB0,0xFF, + 0x00,0x59,0xB3,0xFF,0x02,0x69,0xD0,0xFF,0x00,0x6E,0xD4,0xFF,0x01,0x61,0xC5,0xFF,0x00,0x5E,0xB0,0xFF, + 0x02,0x4D,0xA8,0xFF,0x02,0x51,0xAE,0xFF,0x00,0x56,0xAF,0xFF,0x00,0x53,0xAE,0xFF,0x02,0x54,0xAA,0xFF, + 0x01,0x52,0xAE,0xFF,0x04,0x50,0xA6,0xFF,0x00,0x52,0xB2,0xFF,0x09,0x55,0xB3,0xFF,0x01,0x4C,0x9F,0xFF, + 0x00,0x4A,0x9A,0xFF,0x01,0x50,0xAC,0xFF,0x01,0x51,0xB0,0xFF,0x00,0x53,0xAF,0xFF,0x01,0x51,0xB4,0xFF, + 0x00,0x5B,0xB8,0xFF,0x03,0x58,0xB5,0xFF,0x02,0x52,0xB3,0xFF,0x03,0x54,0xAD,0xFF,0x01,0x53,0xA7,0xFF, + 0x00,0x57,0xBE,0xFF,0x05,0x57,0xBA,0xFF,0x12,0x58,0x96,0xFF,0x1E,0x64,0x98,0xFF,0x2E,0x4A,0x4D,0xFF, + 0x4F,0x67,0x0F,0xFF,0x80,0xA7,0x00,0xFF,0x91,0xAC,0x05,0xFF,0x8D,0xA9,0x00,0xFF,0x8A,0xAE,0x04,0xFF, + 0x8F,0xAD,0x00,0xFF,0x8F,0xAB,0x01,0xFF,0xB5,0xDE,0x06,0xFF,0xC6,0xE1,0x56,0xFF,0x18,0x40,0x4C,0xFF, + 0x00,0x2B,0x51,0xFF,0x01,0x53,0xA7,0xFF,0x05,0x4F,0xAE,0xFF,0x00,0x52,0xAC,0xFF,0x00,0x55,0xAE,0xFF, + 0x04,0x51,0xAD,0xFF,0x02,0x5F,0xC6,0xFF,0x02,0x78,0xF6,0xFF,0x32,0x6E,0x66,0xFF,0x2B,0x35,0x01,0xFF, + 0x6B,0x94,0x00,0xFF,0x90,0xAC,0x02,0xFF,0x88,0xAD,0x00,0xFF,0x92,0xB0,0x00,0xFF,0x85,0xAA,0x02,0xFF, + 0x9D,0xBC,0x06,0xFF,0xAB,0xE8,0x0F,0xFF,0x1C,0x51,0x71,0xFF,0x00,0x31,0x63,0xFF,0x01,0x54,0xA4,0xFF, + 0x00,0x53,0xA6,0xFF,0x00,0x54,0xAE,0xFF,0x00,0x52,0xB2,0xFF,0x00,0x55,0xA8,0xFF,0x01,0x52,0xAD,0xFF, + 0x01,0x50,0xAC,0xFF,0x04,0x52,0xB4,0xFF,0x00,0x51,0xAC,0xFF,0x00,0x54,0xAB,0xFF,0x00,0x51,0xAE,0xFF, + 0x04,0x55,0xB0,0xFF,0x03,0x52,0xB1,0xFF,0x00,0x4E,0xAF,0xFF,0x02,0x53,0xAE,0xFF,0x00,0x53,0xB3,0xFF, + 0x00,0x52,0xAC,0xFF,0x00,0x55,0xAD,0xFF,0x00,0x58,0xB4,0xFF,0x00,0x51,0xA9,0xFF,0x01,0x52,0xA3,0xFF, + 0x04,0x54,0xAD,0xFF,0x02,0x53,0xAE,0xFF,0x04,0x51,0xA9,0xFF,0x09,0x50,0xAC,0xFF,0x00,0x53,0xA8,0xFF, + 0x03,0x55,0xAB,0xFF,0x00,0x51,0xA4,0xFF,0x00,0x54,0xA7,0xFF,0x03,0x54,0xAF,0xFF,0x00,0x50,0xA1,0xFF, + 0x07,0x5E,0xA1,0xFF,0x1B,0x66,0xA7,0xFF,0x36,0x73,0x74,0xFF,0x2E,0x49,0x16,0xFF,0x64,0x7B,0x06,0xFF, + 0x83,0xA8,0x02,0xFF,0x8D,0xAA,0x00,0xFF,0x8F,0xAD,0x00,0xFF,0x89,0xAD,0x05,0xFF,0x8A,0xAB,0x00,0xFF, + 0x8E,0xAD,0x00,0xFF,0xAB,0xD4,0x00,0xFF,0xCF,0xEC,0x46,0xFF,0x1F,0x50,0x4C,0xFF,0x00,0x14,0x46,0xFF, + 0x00,0x4C,0x99,0xFF,0x02,0x4E,0xAC,0xFF,0x00,0x54,0xAC,0xFF,0x00,0x50,0xA5,0xFF,0x00,0x54,0xB1,0xFF, + 0x00,0x55,0xB6,0xFF,0x01,0x7B,0xFF,0xFF,0x30,0x65,0x87,0xFF,0x3E,0x47,0x10,0xFF,0x78,0x9A,0x07,0xFF, + 0x90,0xAD,0x03,0xFF,0x8E,0xAC,0x00,0xFF,0x8D,0xA3,0x02,0xFF,0x8D,0xAF,0x00,0xFF,0x97,0xB5,0x07,0xFF, + 0xB3,0xE4,0x0C,0xFF,0x22,0x4F,0x79,0xFF,0x00,0x28,0x58,0xFF,0x00,0x4B,0x9D,0xFF,0x07,0x51,0xAA,0xFF, + 0x04,0x50,0xB0,0xFF,0x00,0x51,0xAD,0xFF,0x00,0x51,0xB1,0xFF,0x00,0x51,0xAB,0xFF,0x00,0x51,0xB1,0xFF, + 0x03,0x54,0xB0,0xFF,0x03,0x54,0xB0,0xFF,0x09,0x4F,0xB1,0xFF,0x01,0x51,0xAA,0xFF,0x00,0x51,0xA3,0xFF, + 0x00,0x52,0xA8,0xFF,0x00,0x55,0xAA,0xFF,0x00,0x55,0xA6,0xFF,0x00,0x51,0xAA,0xFF,0x00,0x55,0xB2,0xFF, + 0x00,0x58,0xA1,0xFF,0x00,0x5A,0xB0,0xFF,0x00,0x53,0xAB,0xFF,0x06,0x54,0xA9,0xFF,0x01,0x50,0xAC,0xFF, + 0x00,0x52,0xAE,0xFF,0x00,0x54,0xAD,0xFF,0x00,0x55,0xAF,0xFF,0x05,0x50,0xB5,0xFF,0x08,0x50,0xB6,0xFF, + 0x01,0x51,0xB0,0xFF,0x00,0x53,0xB3,0xFF,0x04,0x4E,0xAF,0xFF,0x0F,0x59,0xA0,0xFF,0x0E,0x5F,0x8E,0xFF, + 0x2C,0x74,0xAE,0xFF,0x43,0x70,0x51,0xFF,0x4B,0x61,0x0F,0xFF,0x7B,0x91,0x02,0xFF,0x8A,0xAB,0x02,0xFF, + 0x90,0xAA,0x0B,0xFF,0x8E,0xAD,0x00,0xFF,0x8B,0xB0,0x01,0xFF,0x8C,0xAC,0x03,0xFF,0x8D,0xAB,0x00,0xFF, + 0xA7,0xCF,0x00,0xFF,0xDA,0xFD,0x2D,0xFF,0x1B,0x4A,0x52,0xFF,0x06,0x0B,0x1F,0xFF,0x00,0x43,0x8A,0xFF, + 0x04,0x52,0xB4,0xFF,0x00,0x52,0xA8,0xFF,0x05,0x50,0xAB,0xFF,0x00,0x55,0xA5,0xFF,0x00,0x50,0xB3,0xFF, + 0x00,0x72,0xF8,0xFF,0x3A,0x68,0x5D,0xFF,0x48,0x59,0x00,0xFF,0x8D,0xAE,0x00,0xFF,0x8A,0xAB,0x00,0xFF, + 0x8A,0xB0,0x03,0xFF,0x8C,0xAE,0x02,0xFF,0x8C,0xAF,0x00,0xFF,0x90,0xB2,0x06,0xFF,0xB8,0xDA,0x07,0xFF, + 0x23,0x86,0x67,0xFF,0x00,0x28,0x50,0xFF,0x02,0x47,0x94,0xFF,0x02,0x51,0xB0,0xFF,0x01,0x50,0xAF,0xFF, + 0x04,0x54,0xAD,0xFF,0x04,0x53,0xB2,0xFF,0x03,0x55,0xAB,0xFF,0x03,0x54,0xAF,0xFF,0x00,0x53,0xA6,0xFF, + 0x00,0x52,0xAC,0xFF,0x01,0x53,0xA7,0xFF,0x00,0x57,0xAA,0xFF,0x00,0x54,0xAE,0xFF,0x02,0x53,0xAF,0xFF, + 0x00,0x52,0xAE,0xFF,0x01,0x4D,0xAB,0xFF,0x06,0x4D,0xA7,0xFF,0x03,0x53,0xA8,0xFF,0x03,0x56,0xB2,0xFF, + 0x01,0x53,0xB6,0xFF,0x00,0x4F,0xAE,0xFF,0x01,0x50,0xAC,0xFF,0x03,0x51,0xB3,0xFF,0x05,0x54,0xB3,0xFF, + 0x03,0x53,0xAA,0xFF,0x00,0x50,0xA9,0xFF,0x00,0x51,0xAC,0xFF,0x00,0x50,0xA7,0xFF,0x00,0x53,0xAE,0xFF, + 0x01,0x5B,0xBB,0xFF,0x04,0x55,0xAE,0xFF,0x14,0x5F,0xA3,0xFF,0x0F,0x57,0x89,0xFF,0x27,0x67,0x8D,0xFF, + 0x3F,0x5C,0x3E,0xFF,0x6B,0x81,0x03,0xFF,0x88,0xA1,0x00,0xFF,0x8C,0xAD,0x06,0xFF,0x8E,0xAB,0x01,0xFF, + 0x8D,0xAC,0x00,0xFF,0x8A,0xAE,0x02,0xFF,0x8C,0xAE,0x00,0xFF,0x90,0xAD,0x07,0xFF,0x96,0xBF,0x00,0xFF, + 0xD5,0xFF,0x13,0xFF,0x4C,0x72,0x65,0xFF,0x02,0x04,0x00,0xFF,0x00,0x2F,0x65,0xFF,0x03,0x4F,0xAF,0xFF, + 0x01,0x52,0xAB,0xFF,0x03,0x53,0xAC,0xFF,0x04,0x52,0xB6,0xFF,0x01,0x5C,0xAB,0xFF,0x0E,0x6B,0xC8,0xFF, + 0x3F,0x58,0x3A,0xFF,0x58,0x73,0x00,0xFF,0x8F,0xAC,0x02,0xFF,0x8B,0xAC,0x03,0xFF,0x8D,0xAA,0x02,0xFF, + 0x8B,0xAC,0x00,0xFF,0x8C,0xAD,0x00,0xFF,0x87,0xAC,0x07,0xFF,0xBD,0xED,0x0B,0xFF,0x71,0xB9,0x65,0xFF, + 0x0D,0x41,0x66,0xFF,0x01,0x46,0x8B,0xFF,0x00,0x55,0xB2,0xFF,0x00,0x55,0xA5,0xFF,0x02,0x54,0xA8,0xFF, + 0x02,0x50,0xA3,0xFF,0x02,0x4E,0xAC,0xFF,0x03,0x54,0xA6,0xFF,0x00,0x51,0xAC,0xFF,0x00,0x53,0xB3,0xFF, + 0x01,0x51,0xB4,0xFF,0x00,0x52,0xAF,0xFF,0x01,0x4F,0xB1,0xFF,0x07,0x51,0xB0,0xFF,0x00,0x54,0xAF,0xFF, + 0x01,0x54,0xB2,0xFF,0x06,0x55,0xB1,0xFF,0x00,0x51,0xAB,0xFF,0x04,0x56,0xBA,0xFF,0x01,0x51,0xB0,0xFF, + 0x00,0x53,0xA4,0xFF,0x00,0x52,0xA2,0xFF,0x00,0x53,0xAD,0xFF,0x00,0x4E,0xAA,0xFF,0x03,0x50,0xA8,0xFF, + 0x03,0x53,0xB2,0xFF,0x00,0x57,0xB1,0xFF,0x03,0x53,0xA8,0xFF,0x00,0x52,0xAC,0xFF,0x02,0x5B,0xB7,0xFF, + 0x0D,0x5F,0xB1,0xFF,0x0D,0x58,0x92,0xFF,0x22,0x5D,0x7D,0xFF,0x29,0x50,0x57,0xFF,0x4A,0x63,0x2A,0xFF, + 0x7A,0x99,0x00,0xFF,0x8F,0xB0,0x01,0xFF,0x8B,0xB0,0x01,0xFF,0x8C,0xAE,0x00,0xFF,0x8E,0xAF,0x00,0xFF, + 0x8D,0xAE,0x07,0xFF,0x8A,0xAB,0x00,0xFF,0x8F,0xAB,0x01,0xFF,0x8B,0xB4,0x00,0xFF,0xCD,0xFF,0x06,0xFF, + 0xAA,0xCF,0x5D,0xFF,0x00,0x07,0x07,0xFF,0x00,0x1E,0x3B,0xFF,0x01,0x4C,0x9F,0xFF,0x00,0x51,0xAF,0xFF, + 0x02,0x52,0xA7,0xFF,0x00,0x51,0xAE,0xFF,0x0D,0x59,0xA4,0xFF,0x15,0x49,0x5F,0xFF,0x43,0x57,0x10,0xFF, + 0x77,0x93,0x02,0xFF,0x8B,0xA8,0x00,0xFF,0x8B,0xB1,0x00,0xFF,0x89,0xAE,0x00,0xFF,0x89,0xB0,0x00,0xFF, + 0x88,0xAD,0x00,0xFF,0x89,0xAB,0x00,0xFF,0xA5,0xD1,0x02,0xFF,0x75,0xDF,0x3F,0xFF,0x16,0x52,0x6C,0xFF, + 0x00,0x35,0x75,0xFF,0x00,0x4F,0xAE,0xFF,0x05,0x53,0xA8,0xFF,0x06,0x53,0xAD,0xFF,0x02,0x51,0xAE,0xFF, + 0x02,0x51,0xB8,0xFF,0x01,0x55,0xAF,0xFF,0x02,0x51,0xAE,0xFF,0x04,0x50,0xAE,0xFF,0x04,0x52,0xA5,0xFF, + 0x01,0x53,0x9F,0xFF,0x04,0x4F,0xA0,0xFF,0x05,0x4E,0xAA,0xFF,0x00,0x52,0xAB,0xFF,0x00,0x53,0xA8,0xFF, + 0x05,0x52,0xAC,0xFF,0x04,0x50,0xB0,0xFF,0x00,0x58,0xB2,0xFF,0x00,0x51,0xA4,0xFF,0x00,0x49,0x8C,0xFF, + 0x02,0x44,0x80,0xFF,0x07,0x44,0x87,0xFF,0x05,0x45,0x8D,0xFF,0x00,0x49,0x96,0xFF,0x00,0x51,0xAA,0xFF, + 0x03,0x4E,0xAB,0xFF,0x04,0x51,0xA9,0xFF,0x00,0x55,0xAC,0xFF,0x03,0x5B,0xB4,0xFF,0x13,0x66,0xB2,0xFF, + 0x23,0x72,0x99,0xFF,0x35,0x70,0x6C,0xFF,0x32,0x4D,0x2E,0xFF,0x60,0x7C,0x0D,0xFF,0x85,0xAA,0x00,0xFF, + 0x89,0xAD,0x01,0xFF,0x84,0xA9,0x00,0xFF,0x8D,0xAF,0x01,0xFF,0x89,0xA9,0x00,0xFF,0x8E,0xAE,0x03,0xFF, + 0x8C,0xAB,0x07,0xFF,0x8C,0xAA,0x00,0xFF,0x8F,0xB6,0x01,0xFF,0xC4,0xF8,0x02,0xFF,0xDA,0xFF,0x34,0xFF, + 0x29,0x47,0x47,0xFF,0x02,0x1A,0x32,0xFF,0x01,0x46,0x91,0xFF,0x00,0x52,0xAD,0xFF,0x03,0x50,0xBA,0xFF, + 0x03,0x6D,0xC3,0xFF,0x36,0x63,0x8D,0xFF,0x3B,0x4D,0x23,0xFF,0x62,0x81,0x00,0xFF,0x89,0xA4,0x00,0xFF, + 0x8F,0xAC,0x02,0xFF,0x89,0xAE,0x00,0xFF,0x91,0xA7,0x00,0xFF,0x95,0xAD,0x00,0xFF,0x8F,0xAB,0x08,0xFF, + 0x92,0xAD,0x00,0xFF,0x89,0xB2,0x00,0xFF,0xB6,0xE5,0x09,0xFF,0x40,0x7A,0x51,0xFF,0x09,0x31,0x65,0xFF, + 0x00,0x4B,0x91,0xFF,0x01,0x4E,0x96,0xFF,0x00,0x4A,0x8E,0xFF,0x00,0x47,0x98,0xFF,0x00,0x46,0x8D,0xFF, + 0x00,0x39,0x7C,0xFF,0x00,0x2F,0x60,0xFF,0x02,0x28,0x57,0xFF,0x00,0x25,0x3E,0xFF,0x00,0x27,0x55,0xFF, + 0x01,0x35,0x67,0xFF,0x02,0x43,0x85,0xFF,0x04,0x52,0x9D,0xFF,0x01,0x57,0xAA,0xFF,0x00,0x50,0xB1,0xFF, + 0x00,0x53,0xAD,0xFF,0x00,0x5B,0xB7,0xFF,0x00,0x58,0xBA,0xFF,0x00,0x3F,0x87,0xFF,0x03,0x20,0x42,0xFF, + 0x00,0x0C,0x1F,0xFF,0x00,0x19,0x32,0xFF,0x00,0x1F,0x43,0xFF,0x05,0x29,0x5B,0xFF,0x00,0x39,0x7E,0xFF, + 0x02,0x4A,0x96,0xFF,0x01,0x58,0xB5,0xFF,0x06,0x5F,0xBD,0xFF,0x0E,0x62,0xAB,0xFF,0x24,0x75,0xAC,0xFF, + 0x1C,0x59,0x6C,0xFF,0x1F,0x39,0x1E,0xFF,0x53,0x69,0x00,0xFF,0x67,0x85,0x03,0xFF,0x66,0x82,0x07,0xFF, + 0x65,0x7E,0x08,0xFF,0x65,0x7D,0x01,0xFF,0x69,0x85,0x00,0xFF,0x7B,0x97,0x04,0xFF,0x83,0xA7,0x00,0xFF, + 0x87,0xA6,0x02,0xFF,0x8A,0xAC,0x00,0xFF,0xA4,0xCE,0x00,0xFF,0xD0,0xFA,0x1A,0xFF,0x52,0x82,0x68,0xFF, + 0x06,0x17,0x35,0xFF,0x00,0x40,0x89,0xFF,0x03,0x57,0xAF,0xFF,0x00,0x5B,0xB5,0xFF,0x1C,0x82,0xD6,0xFF, + 0x62,0x83,0x32,0xFF,0x7B,0x91,0x12,0xFF,0x84,0xA9,0x00,0xFF,0x8B,0xAC,0x00,0xFF,0x8C,0xAC,0x01,0xFF, + 0x8A,0xAC,0x00,0xFF,0x8C,0xAE,0x00,0xFF,0x8C,0xA5,0x00,0xFF,0x87,0xAF,0x00,0xFF,0x86,0x9F,0x05,0xFF, + 0x87,0xA0,0x00,0xFF,0x9E,0xD7,0x00,0xFF,0x54,0x81,0x24,0xFF,0x00,0x18,0x40,0xFF,0x00,0x27,0x5A,0xFF, + 0x00,0x27,0x5E,0xFF,0x00,0x25,0x53,0xFF,0x08,0x36,0x67,0xFF,0x13,0x49,0x6D,0xFF,0x16,0x48,0x6B,0xFF, + 0x21,0x4F,0x5F,0xFF,0x2D,0x52,0x58,0xFF,0x24,0x3F,0x36,0xFF,0x1A,0x32,0x3E,0xFF,0x0F,0x3B,0x3E,0xFF, + 0x00,0x2E,0x4F,0xFF,0x00,0x22,0x5F,0xFF,0x03,0x3A,0x7B,0xFF,0x01,0x4A,0xA8,0xFF,0x07,0x54,0xAE,0xFF, + 0x02,0x5A,0xB4,0xFF,0x05,0x65,0xCB,0xFF,0x06,0x53,0x97,0xFF,0x26,0x49,0x4B,0xFF,0x39,0x4C,0x2C,0xFF, + 0x41,0x63,0x4B,0xFF,0x17,0x36,0x38,0xFF,0x02,0x0D,0x1F,0xFF,0x00,0x10,0x28,0xFF,0x00,0x2B,0x52,0xFF, + 0x00,0x42,0x8D,0xFF,0x0D,0x52,0x97,0xFF,0x19,0x5A,0x76,0xFF,0x1E,0x5D,0x7E,0xFF,0x25,0x51,0x5C,0xFF, + 0x3D,0x49,0x09,0xFF,0x2B,0x32,0x00,0xFF,0x27,0x30,0x1D,0xFF,0x3C,0x4B,0x20,0xFF,0x3B,0x46,0x1B,0xFF, + 0x1F,0x27,0x10,0xFF,0x43,0x54,0x06,0xFF,0x5B,0x73,0x01,0xFF,0x71,0x93,0x00,0xFF,0x74,0x95,0x00,0xFF, + 0x7C,0x99,0x03,0xFF,0x84,0xA4,0x05,0xFF,0xBD,0xEB,0x16,0xFF,0x3D,0x74,0x4D,0xFF,0x04,0x15,0x31,0xFF, + 0x01,0x44,0x8A,0xFF,0x00,0x51,0xAC,0xFF,0x00,0x69,0xCC,0xFF,0x10,0x64,0xAD,0xFF,0x5D,0x75,0x07,0xFF, + 0x78,0x9A,0x08,0xFF,0x90,0xAB,0x00,0xFF,0x86,0xAF,0x00,0xFF,0x8C,0xAC,0x03,0xFF,0x8E,0xAC,0x00,0xFF, + 0x84,0xAE,0x04,0xFF,0x8A,0xA6,0x00,0xFF,0x79,0xAB,0x00,0xFF,0x7A,0x9C,0x00,0xFF,0x6F,0x84,0x00,0xFF, + 0x81,0x98,0x12,0xFF,0x49,0x63,0x24,0xFF,0x07,0x22,0x37,0xFF,0x18,0x43,0x53,0xFF,0x24,0x48,0x46,0xFF, + 0x30,0x4E,0x32,0xFF,0x58,0x7D,0x2D,0xFF,0x7C,0xA8,0x39,0xFF,0x87,0xBB,0x2A,0xFF,0x9F,0xD3,0x28,0xFF, + 0xAF,0xE3,0x1C,0xFF,0xA6,0xD7,0x19,0xFF,0x9C,0xC5,0x13,0xFF,0x8B,0xC2,0x1F,0xFF,0x48,0x6E,0x3D,0xFF, + 0x08,0x0E,0x24,0xFF,0x00,0x1B,0x28,0xFF,0x00,0x45,0x83,0xFF,0x03,0x52,0xB1,0xFF,0x00,0x5C,0xB1,0xFF, + 0x02,0x6C,0xD9,0xFF,0x31,0x7B,0x7E,0xFF,0x73,0x9E,0x2A,0xFF,0xAD,0xE7,0x16,0xFF,0xBA,0xF1,0x22,0xFF, + 0xA3,0xE1,0x38,0xFF,0x46,0x9E,0x64,0xFF,0x1E,0x4A,0x4B,0xFF,0x13,0x35,0x37,0xFF,0x16,0x38,0x54,0xFF, + 0x17,0x54,0x70,0xFF,0x30,0x6C,0x6D,0xFF,0x4B,0x74,0x4C,0xFF,0x4A,0x71,0x32,0xFF,0x59,0x75,0x0E,0xFF, + 0x25,0x34,0x15,0xFF,0x0D,0x2B,0x29,0xFF,0x1A,0x58,0x7F,0xFF,0x2C,0x82,0xA3,0xFF,0x2F,0x76,0x78,0xFF, + 0x32,0x52,0x2D,0xFF,0x3A,0x47,0x01,0xFF,0x37,0x47,0x08,0xFF,0x3E,0x55,0x00,0xFF,0x55,0x64,0x09,0xFF, + 0x54,0x6A,0x06,0xFF,0x69,0x8D,0x11,0xFF,0x22,0x41,0x3C,0xFF,0x01,0x34,0x61,0xFF,0x06,0x50,0xA7,0xFF, + 0x00,0x52,0xA5,0xFF,0x00,0x6A,0xE4,0xFF,0x26,0x75,0x9E,0xFF,0x36,0x46,0x07,0xFF,0x50,0x59,0x0A,0xFF, + 0x6F,0x97,0x00,0xFF,0x87,0xA3,0x01,0xFF,0x81,0xA3,0x04,0xFF,0x79,0x9E,0x00,0xFF,0x80,0xA8,0x0A,0xFF, + 0x74,0x90,0x00,0xFF,0x5E,0x73,0x00,0xFF,0x4F,0x6B,0x00,0xFF,0x42,0x68,0x1D,0xFF,0x66,0x8A,0x40,0xFF, + 0x45,0x70,0x66,0xFF,0x36,0x5D,0x3E,0xFF,0x58,0x84,0x25,0xFF,0x74,0xA8,0x44,0xFF,0x7C,0xA7,0x19,0xFF, + 0x90,0xB7,0x0C,0xFF,0x9A,0xCA,0x12,0xFF,0x92,0xBB,0x07,0xFF,0x98,0xBD,0x00,0xFF,0x9D,0xC6,0x14,0xFF, + 0x9F,0xBE,0x00,0xFF,0x98,0xBB,0x00,0xFF,0xBD,0xEE,0x06,0xFF,0xBB,0xF4,0x2B,0xFF,0x64,0x8A,0x4D,0xFF, + 0x0A,0x2F,0x49,0xFF,0x00,0x35,0x81,0xFF,0x03,0x53,0xAA,0xFF,0x00,0x62,0xC7,0xFF,0x03,0x73,0xF3,0xFF, + 0x42,0x74,0x57,0xFF,0x52,0x71,0x00,0xFF,0x8F,0xB8,0x02,0xFF,0xAE,0xD8,0x00,0xFF,0xC0,0xED,0x00,0xFF, + 0xB6,0xFA,0x29,0xFF,0x98,0xE1,0x32,0xFF,0x88,0xBC,0x34,0xFF,0x79,0xA3,0x33,0xFF,0x83,0xBD,0x33,0xFF, + 0x8B,0xC5,0x33,0xFF,0x94,0xC2,0x2B,0xFF,0x99,0xD4,0x20,0xFF,0x67,0x9A,0x35,0xFF,0x42,0x72,0x62,0xFF, + 0x0C,0x41,0x6D,0xFF,0x00,0x4F,0xAB,0xFF,0x02,0x78,0xE4,0xFF,0x0C,0x8B,0xF6,0xFF,0x2D,0x91,0xCC,0xFF, + 0x4D,0x92,0x80,0xFF,0x48,0x78,0x46,0xFF,0x48,0x6D,0x39,0xFF,0x5A,0x7C,0x26,0xFF,0x4D,0x75,0x2C,0xFF, + 0x17,0x41,0x4D,0xFF,0x00,0x32,0x5C,0xFF,0x00,0x44,0x99,0xFF,0x00,0x53,0xB1,0xFF,0x00,0x51,0xB5,0xFF, + 0x00,0x6D,0xE0,0xFF,0x0C,0x8B,0xF4,0xFF,0x2D,0x6F,0x63,0xFF,0x3D,0x49,0x0B,0xFF,0x41,0x4F,0x00,0xFF, + 0x48,0x52,0x09,0xFF,0x52,0x67,0x00,0xFF,0x60,0x72,0x02,0xFF,0x5C,0x71,0x00,0xFF,0x54,0x72,0x1C,0xFF, + 0x56,0x83,0x40,0xFF,0x58,0x8F,0x7C,0xFF,0x2B,0x81,0x9C,0xFF,0x21,0x8B,0xE3,0xFF,0x2B,0xA1,0xD3,0xFF, + 0x43,0x8E,0x77,0xFF,0x4F,0x73,0x29,0xFF,0x69,0x8B,0x12,0xFF,0x7D,0x9A,0x02,0xFF,0x8C,0xAC,0x0B,0xFF, + 0x8B,0xB0,0x00,0xFF,0x94,0xB7,0x01,0xFF,0x91,0xB5,0x0B,0xFF,0x91,0xB7,0x00,0xFF,0x93,0xB3,0x00,0xFF, + 0x97,0xBB,0x01,0xFF,0x9B,0xBE,0x00,0xFF,0xBA,0xE0,0x01,0xFF,0x8A,0xB0,0x0B,0xFF,0x12,0x3A,0x46,0xFF, + 0x00,0x39,0x7C,0xFF,0x03,0x52,0xAF,0xFF,0x00,0x64,0xC2,0xFF,0x00,0x70,0xF0,0xFF,0x34,0x4F,0x40,0xFF, + 0x20,0x24,0x01,0xFF,0x75,0x91,0x08,0xFF,0x91,0xB5,0x00,0xFF,0x9C,0xBA,0x04,0xFF,0xA0,0xCC,0x00,0xFF, + 0xAC,0xDB,0x01,0xFF,0xAB,0xD1,0x08,0xFF,0xAB,0xD5,0x09,0xFF,0xA4,0xD0,0x0B,0xFF,0xA2,0xCE,0x09,0xFF, + 0xAB,0xD6,0x00,0xFF,0xC6,0xF8,0x00,0xFF,0x76,0xA6,0x43,0xFF,0x12,0x59,0x79,0xFF,0x0C,0x50,0x91,0xFF, + 0x03,0x4F,0xA3,0xFF,0x00,0x59,0xB3,0xFF,0x00,0x6F,0xD3,0xFF,0x00,0x76,0xF0,0xFF,0x00,0x77,0xFE,0xFF, + 0x05,0x81,0xFB,0xFF,0x11,0x79,0xD2,0xFF,0x2A,0x8C,0xE5,0xFF,0x2F,0x8F,0xE5,0xFF,0x0C,0x62,0xC7,0xFF, + 0x00,0x4C,0x84,0xFF,0x00,0x4B,0x91,0xFF,0x00,0x53,0x9E,0xFF,0x00,0x55,0xAF,0xFF,0x07,0x5B,0xBB,0xFF, + 0x00,0x72,0xEB,0xFF,0x0A,0x82,0xFC,0xFF,0x01,0x74,0xCF,0xFF,0x2B,0x7D,0x79,0xFF,0x3D,0x62,0x2F,0xFF, + 0x41,0x60,0x25,0xFF,0x4A,0x6E,0x26,0xFF,0x3D,0x71,0x4B,0xFF,0x15,0x5B,0xA1,0xFF,0x00,0x72,0xD9,0xFF, + 0x00,0x78,0xF0,0xFF,0x00,0x70,0xDC,0xFF,0x00,0x6F,0xEF,0xFF,0x08,0x86,0xFF,0xFF,0x1F,0x7F,0xB9,0xFF, + 0x4F,0x73,0x35,0xFF,0x68,0x80,0x00,0xFF,0x92,0xAF,0x07,0xFF,0x87,0xA8,0x00,0xFF,0x8E,0xA8,0x06,0xFF, + 0x90,0xAE,0x00,0xFF,0x8A,0xAE,0x04,0xFF,0x8C,0xAB,0x00,0xFF,0x8D,0xAF,0x00,0xFF,0x85,0xA8,0x04,0xFF, + 0x8F,0xB4,0x02,0xFF,0x7A,0x9A,0x08,0xFF,0x38,0x5C,0x2C,0xFF,0x00,0x35,0x49,0xFF,0x00,0x47,0x88,0xFF, + 0x02,0x50,0xB2,0xFF,0x00,0x5B,0xBA,0xFF,0x04,0x76,0xFD,0xFF,0x33,0x62,0x5C,0xFF,0x0C,0x0E,0x00,0xFF, + 0x5C,0x74,0x04,0xFF,0x83,0xAC,0x00,0xFF,0x8B,0xB2,0x01,0xFF,0x8F,0xB6,0x05,0xFF,0x9E,0xB0,0x04,0xFF, + 0x96,0xB0,0x00,0xFF,0x95,0xB7,0x01,0xFF,0x96,0xB6,0x00,0xFF,0x90,0xB3,0x00,0xFF,0x9D,0xBF,0x08,0xFF, + 0xC5,0xEB,0x04,0xFF,0x4D,0x76,0x30,0xFF,0x0B,0x35,0x4B,0xFF,0x05,0x3F,0x89,0xFF,0x00,0x4F,0xA4,0xFF, + 0x00,0x53,0xA6,0xFF,0x01,0x55,0xAF,0xFF,0x01,0x56,0xB0,0xFF,0x02,0x56,0xB8,0xFF,0x06,0x5A,0xBA,0xFF, + 0x00,0x6D,0xD4,0xFF,0x00,0x6B,0xE8,0xFF,0x00,0x69,0xE4,0xFF,0x00,0x71,0xDB,0xFF,0x00,0x54,0xBB,0xFF, + 0x00,0x4B,0xA8,0xFF,0x02,0x52,0xA9,0xFF,0x01,0x4F,0xB1,0xFF,0x00,0x4F,0xA8,0xFF,0x00,0x5B,0xBB,0xFF, + 0x07,0x62,0xCD,0xFF,0x02,0x74,0xF1,0xFF,0x02,0x87,0xFD,0xFF,0x24,0x92,0xF3,0xFF,0x1E,0x7A,0xCD,0xFF, + 0x22,0x7D,0xB6,0xFF,0x0A,0x6D,0xCA,0xFF,0x04,0x55,0xB1,0xFF,0x00,0x54,0xBB,0xFF,0x00,0x50,0xAA,0xFF, + 0x05,0x50,0xB5,0xFF,0x06,0x56,0xB5,0xFF,0x00,0x69,0xDF,0xFF,0x09,0x61,0xB8,0xFF,0x44,0x62,0x2E,0xFF, + 0x73,0x93,0x01,0xFF,0x88,0xB4,0x00,0xFF,0x8D,0xB6,0x02,0xFF,0x8E,0xA9,0x04,0xFF,0x8A,0xAA,0x01,0xFF, + 0x8C,0xAD,0x00,0xFF,0x8F,0xAB,0x00,0xFF,0x85,0xAF,0x05,0xFF,0x93,0xB1,0x03,0xFF,0x86,0xA7,0x00,0xFF, + 0x68,0x87,0x2A,0xFF,0x2A,0x54,0x62,0xFF,0x02,0x33,0x76,0xFF,0x0A,0x51,0xA9,0xFF,0x00,0x52,0xA9,0xFF, + 0x00,0x5B,0xB5,0xFF,0x00,0x7C,0xF6,0xFF,0x2C,0x8C,0xB2,0xFF,0x17,0x26,0x05,0xFF,0x41,0x51,0x00,0xFF, + 0x86,0xA7,0x00,0xFF,0x8A,0xAB,0x00,0xFF,0x8A,0xAA,0x01,0xFF,0x8C,0xAE,0x00,0xFF,0x8B,0xB0,0x00,0xFF, + 0x8A,0xB0,0x05,0xFF,0x8E,0xA9,0x00,0xFF,0x8F,0xAD,0x00,0xFF,0x98,0xC1,0x03,0xFF,0x92,0xBC,0x28,0xFF, + 0x2D,0x5F,0x66,0xFF,0x05,0x31,0x4E,0xFF,0x00,0x37,0x7D,0xFF,0x00,0x4B,0x99,0xFF,0x07,0x55,0xAA,0xFF, + 0x00,0x4D,0xAA,0xFF,0x00,0x51,0xA6,0xFF,0x00,0x55,0xAF,0xFF,0x00,0x4F,0xAB,0xFF,0x02,0x4F,0xAB,0xFF, + 0x01,0x4E,0xAA,0xFF,0x00,0x58,0xA7,0xFF,0x00,0x5C,0xB0,0xFF,0x03,0x58,0xB5,0xFF,0x01,0x55,0xB8,0xFF, + 0x00,0x54,0xAD,0xFF,0x00,0x51,0xAC,0xFF,0x01,0x52,0xAE,0xFF,0x00,0x57,0xAF,0xFF,0x07,0x51,0xB0,0xFF, + 0x00,0x4E,0xB3,0xFF,0x00,0x60,0xC6,0xFF,0x03,0x74,0xD4,0xFF,0x00,0x71,0xDB,0xFF,0x00,0x6F,0xCF,0xFF, + 0x01,0x56,0xB0,0xFF,0x06,0x53,0xA3,0xFF,0x00,0x51,0xAC,0xFF,0x03,0x52,0xAF,0xFF,0x07,0x51,0xA6,0xFF, + 0x00,0x55,0xA5,0xFF,0x00,0x73,0xDD,0xFF,0x11,0x65,0xAE,0xFF,0x31,0x40,0x19,0xFF,0x63,0x7D,0x00,0xFF, + 0x88,0xBA,0x01,0xFF,0x87,0xAD,0x00,0xFF,0x8E,0xAD,0x00,0xFF,0x8B,0xB0,0x01,0xFF,0x8A,0xA7,0x00,0xFF, + 0x91,0xAF,0x01,0xFF,0x8E,0xB4,0x00,0xFF,0xA7,0xD1,0x03,0xFF,0x6B,0xA1,0x31,0xFF,0x25,0x62,0x5D,0xFF, + 0x06,0x56,0xAD,0xFF,0x06,0x54,0xA9,0xFF,0x01,0x55,0xAD,0xFF,0x01,0x51,0xAA,0xFF,0x01,0x56,0xB3,0xFF, + 0x00,0x73,0xFE,0xFF,0x0C,0x86,0xFF,0xFF,0x24,0x43,0x31,0xFF,0x22,0x23,0x01,0xFF,0x78,0x8D,0x00,0xFF, + 0x91,0xAC,0x00,0xFF,0x90,0xAD,0x05,0xFF,0x89,0xB1,0x01,0xFF,0x82,0xA9,0x00,0xFF,0x89,0xB0,0x00,0xFF, + 0x8F,0xA9,0x08,0xFF,0x90,0xAD,0x00,0xFF,0xA8,0xD8,0x08,0xFF,0x6E,0x97,0x5D,0xFF,0x16,0x4B,0x75,0xFF, + 0x02,0x38,0x74,0xFF,0x00,0x44,0x8D,0xFF,0x00,0x48,0x9E,0xFF,0x04,0x4C,0xB0,0xFF,0x09,0x52,0xB1,0xFF, + 0x03,0x55,0xAB,0xFF,0x00,0x51,0xAB,0xFF,0x02,0x52,0xAB,0xFF,0x04,0x56,0xAC,0xFF,0x04,0x53,0xB2,0xFF, + 0x00,0x53,0xAF,0xFF,0x00,0x4F,0xA9,0xFF,0x05,0x50,0xAD,0xFF,0x06,0x51,0xB6,0xFF,0x00,0x52,0xAC,0xFF, + 0x00,0x52,0xA2,0xFF,0x00,0x55,0xA6,0xFF,0x04,0x54,0xA9,0xFF,0x00,0x52,0xA5,0xFF,0x00,0x57,0xB0,0xFF, + 0x01,0x4F,0xB4,0xFF,0x02,0x52,0xA9,0xFF,0x00,0x51,0xA3,0xFF,0x07,0x4F,0xB1,0xFF,0x00,0x55,0xAD,0xFF, + 0x05,0x55,0xB6,0xFF,0x00,0x51,0xAC,0xFF,0x01,0x50,0xAF,0xFF,0x05,0x50,0xAB,0xFF,0x00,0x52,0xB3,0xFF, + 0x00,0x6B,0xE8,0xFF,0x1D,0x7B,0xB8,0xFF,0x1B,0x23,0x0E,0xFF,0x4B,0x54,0x03,0xFF,0x85,0xAE,0x00,0xFF, + 0x8F,0xAF,0x02,0xFF,0x8E,0xAB,0x00,0xFF,0x89,0xB0,0x00,0xFF,0x8F,0xAA,0x03,0xFF,0x89,0xAB,0x00,0xFF, + 0x95,0xB3,0x03,0xFF,0xB1,0xE6,0x00,0xFF,0x4A,0x79,0x73,0xFF,0x0E,0x41,0x6C,0xFF,0x03,0x53,0xAA,0xFF, + 0x00,0x51,0xB1,0xFF,0x00,0x56,0xA9,0xFF,0x06,0x4F,0xAD,0xFF,0x05,0x52,0xAE,0xFF,0x02,0x6C,0xD0,0xFF, + 0x00,0x78,0xFB,0xFF,0x39,0x6B,0x6A,0xFF,0x1C,0x20,0x05,0xFF,0x66,0x7B,0x02,0xFF,0x90,0xAA,0x09,0xFF, + 0x85,0xAC,0x00,0xFF,0x8B,0xA7,0x00,0xFF,0x95,0xB3,0x05,0xFF,0x89,0xA8,0x02,0xFF,0x8C,0xAF,0x00,0xFF, + 0x91,0xB8,0x00,0xFF,0x91,0xBC,0x24,0xFF,0x45,0x71,0x62,0xFF,0x0A,0x39,0x4B,0xFF,0x00,0x3B,0x79,0xFF, + 0x00,0x4B,0x9F,0xFF,0x00,0x52,0xAB,0xFF,0x00,0x59,0xAC,0xFF,0x00,0x53,0xB0,0xFF,0x00,0x52,0xAC,0xFF, + 0x00,0x53,0xA4,0xFF,0x00,0x52,0xB8,0xFF,0x02,0x4C,0xAD,0xFF,0x05,0x50,0xAB,0xFF,0x00,0x51,0xA8,0xFF, + 0x00,0x5B,0xAC,0xFF,0x04,0x4F,0xB5,0xFF,0x04,0x4D,0xAB,0xFF,0x04,0x50,0xAE,0xFF,0x08,0x51,0xB0,0xFF, + 0x05,0x4E,0xAD,0xFF,0x00,0x51,0xB1,0xFF,0x00,0x51,0xAF,0xFF,0x02,0x4C,0xA5,0xFF,0x07,0x56,0xA5,0xFF, + 0x00,0x50,0xA5,0xFF,0x06,0x56,0xAD,0xFF,0x00,0x52,0xAC,0xFF,0x00,0x50,0xB1,0xFF,0x04,0x54,0xA9,0xFF, + 0x01,0x54,0xB2,0xFF,0x00,0x52,0xAD,0xFF,0x03,0x52,0xAF,0xFF,0x07,0x53,0xA9,0xFF,0x00,0x68,0xD7,0xFF, + 0x15,0x8E,0xF9,0xFF,0x19,0x3F,0x42,0xFF,0x31,0x31,0x00,0xFF,0x84,0x9F,0x04,0xFF,0x87,0xA8,0x00,0xFF, + 0x92,0xAB,0x07,0xFF,0x89,0xAC,0x00,0xFF,0x91,0xAE,0x00,0xFF,0x88,0xAC,0x02,0xFF,0x9A,0xB9,0x03,0xFF, + 0xA4,0xD2,0x27,0xFF,0x1B,0x53,0x62,0xFF,0x00,0x34,0x67,0xFF,0x00,0x5A,0xA0,0xFF,0x00,0x52,0xAF,0xFF, + 0x00,0x57,0xA7,0xFF,0x05,0x4D,0xB9,0xFF,0x00,0x50,0xAC,0xFF,0x00,0x66,0xCB,0xFF,0x08,0x86,0xF4,0xFF, + 0x48,0x8E,0x96,0xFF,0x1D,0x29,0x13,0xFF,0x55,0x71,0x02,0xFF,0x8C,0xAA,0x00,0xFF,0x8C,0xB0,0x06,0xFF, + 0x8F,0xAD,0x00,0xFF,0x89,0xA9,0x00,0xFF,0x8F,0xAD,0x00,0xFF,0x8A,0xB6,0x00,0xFF,0x94,0xBB,0x24,0xFF, + 0x7B,0xA7,0x48,0xFF,0x2B,0x65,0x67,0xFF,0x11,0x42,0x60,0xFF,0x00,0x42,0x8A,0xFF,0x09,0x52,0xA1,0xFF, + 0x03,0x4D,0xAC,0xFF,0x01,0x51,0xA8,0xFF,0x01,0x52,0xAD,0xFF,0x03,0x53,0xB6,0xFF,0x00,0x52,0xA6,0xFF, + 0x02,0x52,0xAB,0xFF,0x00,0x57,0xAF,0xFF,0x04,0x54,0xA9,0xFF,0x04,0x51,0xAD,0xFF,0x00,0x4E,0xAB,0xFF, + 0x03,0x53,0xAA,0xFF,0x00,0x57,0xA9,0xFF,0x00,0x54,0xAC,0xFF,0x00,0x51,0xAA,0xFF,0x00,0x51,0xAF,0xFF, + 0x08,0x53,0xAE,0xFF,0x00,0x55,0xA8,0xFF,0x00,0x56,0xB0,0xFF,0x00,0x53,0xAE,0xFF,0x00,0x4E,0xB9,0xFF, + 0x00,0x50,0xAF,0xFF,0x01,0x53,0xA9,0xFF,0x03,0x54,0xA6,0xFF,0x06,0x4E,0xB4,0xFF,0x00,0x4F,0xA4,0xFF, + 0x01,0x56,0xB1,0xFF,0x00,0x53,0xAE,0xFF,0x03,0x4F,0xA5,0xFF,0x01,0x6D,0xDC,0xFF,0x07,0x82,0xF9,0xFF, + 0x2F,0x7F,0x98,0xFF,0x3B,0x46,0x02,0xFF,0x6E,0x83,0x00,0xFF,0x88,0xB0,0x02,0xFF,0x8D,0xA8,0x01,0xFF, + 0x8E,0xAE,0x05,0xFF,0x8F,0xAB,0x00,0xFF,0x8C,0xAE,0x02,0xFF,0xAD,0xDA,0x03,0xFF,0x94,0xB9,0x1C,0xFF, + 0x17,0x3C,0x73,0xFF,0x05,0x34,0x7A,0xFF,0x03,0x52,0xA1,0xFF,0x0B,0x4C,0xB0,0xFF,0x00,0x54,0xAE,0xFF, + 0x00,0x53,0xA6,0xFF, + +}; + +} + +void make_gb_poly(agg::path_storage& ps); +void make_arrows(agg::path_storage& ps); + +//==========================================================the_application +class the_application : public agg::platform_support +{ + typedef agg::gradient_lut, 1024> color_func_type; + + agg::rbox_ctrl m_polygons; + agg::rbox_ctrl m_gradient; + + agg::cbox_ctrl m_stroke; + agg::cbox_ctrl m_refl; + + agg::slider_ctrl m_c1; + agg::slider_ctrl m_c2; + agg::slider_ctrl m_d1; + agg::slider_ctrl m_d2; + agg::slider_ctrl m_clrs; + + agg::polygon_ctrl m_persp; + + agg::rasterizer_scanline_aa<> m_ras; + agg::scanline_p8 m_sl; + agg::span_allocator m_alloc; + + double m_gamma; + bool m_init; + int m_last; + + color_func_type m_colors02; + color_func_type m_colors03; + color_func_type m_colors04; + color_func_type m_colors05; + color_func_type m_colors06; + color_func_type m_colors07; + color_func_type m_colors08; + color_func_type m_colors09; + color_func_type m_colors10; + color_func_type m_colors11; + +public: + ~the_application() + { + } + + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_polygons(5.0, 5.0, 5.0+130.0, 90.0, !flip_y), + m_gradient(145.0, 5.0, 220.0+80.0, 90.0, !flip_y), + m_stroke(305.0 ,77.0 ,"Bitmap Gradient" , !flip_y ), + m_refl(440.0 ,77.0 ,"Reflect" ,!flip_y ), + m_c1(310.0 ,10.0 ,400.0 ,16.0 ,!flip_y ), + m_c2(310.0 ,30.0 ,400.0 ,36.0 ,!flip_y ), + m_d1(410.0 ,10.0 ,500.0 ,16.0 ,!flip_y ), + m_d2(410.0 ,30.0 ,500.0 ,36.0 ,!flip_y ), + m_clrs(310.0 ,50.0 ,500.0 ,58.0 ,!flip_y ), + m_persp(4 ) + { + m_init = true; + + // Controls + m_gradient.add_item("Contour"); + m_gradient.add_item("Auto Contour"); + m_gradient.add_item("Assymetric Conic"); + m_gradient.add_item("Flat Fill"); + m_gradient.cur_item(1); + add_ctrl(m_gradient); + m_gradient.no_transform(); + + m_polygons.add_item("Simple Path"); + m_polygons.add_item("Great Britain"); + m_polygons.add_item("Spiral"); + m_polygons.add_item("Glyph"); + m_polygons.cur_item(0); + add_ctrl(m_polygons); + m_polygons.no_transform(); + + m_last = m_polygons.cur_item(); + + add_ctrl(m_stroke ); + m_stroke.status(false ); + m_stroke.no_transform(); + + add_ctrl(m_refl ); + m_refl.status(true ); + m_refl.no_transform(); + + add_ctrl(m_c1 ); + + m_c1.label("C1=%1.0f" ); + m_c1.range(0.0 ,512.0 ); + m_c1.value(0.0 ); + m_c1.no_transform(); + + add_ctrl(m_c2 ); + + m_c2.label("C2=%1.0f" ); + m_c2.range(0.0 ,512.0 ); + m_c2.value(512.0 ); + m_c2.no_transform(); + + add_ctrl(m_d1 ); + + m_d1.label("D1=%1.0f" ); + m_d1.range(0.0 ,512.0 ); + m_d1.value(0.0 ); + m_d1.no_transform(); + + add_ctrl(m_d2 ); + + m_d2.label("D2=%1.0f" ); + m_d2.range(0.1 ,512.0 ); + m_d2.value(100.0 ); + m_d2.no_transform(); + + add_ctrl(m_clrs ); + + m_clrs.label("Colors=%1.0f" ); + m_clrs.range(2.0 ,11.0 ); + m_clrs.value(2.0 ); + m_clrs.num_steps(9 ); + m_clrs.no_transform(); + + add_ctrl(m_persp ); + + m_persp.in_polygon_check(true ); + m_persp.no_transform(); + m_persp.line_color(agg::rgba(0, 0.3, 0.5, 0.3)); + + // 2 colors gradient + m_colors02.remove_all(); + m_colors02.add_color(0.0, agg::srgba8(178 ,34 ,34 ) ); + m_colors02.add_color(1.0, agg::srgba8(255 ,255 ,0 ) ); + m_colors02.build_lut(); + + // 3 colors gradient + m_colors03.remove_all(); + m_colors03.add_color(0.0, agg::srgba8(245 ,233 ,131 ) ); + m_colors03.add_color(0.5, agg::srgba8(146 ,35 ,219 ) ); + m_colors03.add_color(1.0, agg::srgba8(255 ,35 ,0 ) ); + m_colors03.build_lut(); + + // 4 colors gradient + m_colors04.remove_all(); + m_colors04.add_color(1.0, agg::srgba8(0 ,255 ,0 ) ); + m_colors04.add_color(0.7, agg::srgba8(120 ,0 ,0 ) ); + m_colors04.add_color(0.2, agg::srgba8(120 ,120 ,0 ) ); + m_colors04.add_color(0.0, agg::srgba8(0 ,0 ,255 ) ); + m_colors04.build_lut(); + + // 5 colors gradient + m_colors05.remove_all(); + m_colors05.add_color(0.2, agg::srgba8(230 ,188 ,106 ) ); + m_colors05.add_color(0.4, agg::srgba8(207 ,148 ,31 ) ); + m_colors05.add_color(0.6, agg::srgba8(69 ,56 ,30 ) ); + m_colors05.add_color(0.8, agg::srgba8(43 ,33 ,13 ) ); + m_colors05.add_color(1.0, agg::srgba8(227 ,221 ,209 ) ); + m_colors05.build_lut(); + + // 6 colors gradient + m_colors06.remove_all(); + m_colors06.add_color(0.0, agg::srgba8(125 ,99 ,255 ) ); + m_colors06.add_color(0.2, agg::srgba8(118 ,79 ,210 ) ); + m_colors06.add_color(0.4, agg::srgba8(105 ,58 ,81 ) ); + m_colors06.add_color(0.6, agg::srgba8(217 ,74 ,102 ) ); + m_colors06.add_color(0.8, agg::srgba8(242 ,148 ,90 ) ); + m_colors06.add_color(1.0, agg::srgba8(242 ,200 ,102 ) ); + m_colors06.build_lut(); + + // 7 colors gradient + m_colors07.remove_all(); + m_colors07.add_color(0.00, agg::srgba8(216 ,237 ,232 ) ); + m_colors07.add_color(0.16, agg::srgba8(196 ,214 ,226 ) ); + m_colors07.add_color(0.32, agg::srgba8(175 ,194 ,217 ) ); + m_colors07.add_color(0.48, agg::srgba8(155 ,176 ,210 ) ); + m_colors07.add_color(0.64, agg::srgba8(140 ,162 ,202 ) ); + m_colors07.add_color(0.80, agg::srgba8(130 ,149 ,193 ) ); + m_colors07.add_color(1.00, agg::srgba8(72 ,102 ,165 ) ); + m_colors07.build_lut(); + + // 8 colors gradient + m_colors08.remove_all(); + m_colors08.add_color(0.00, agg::srgba8(255 ,223 ,168 ) ); + m_colors08.add_color(0.14, agg::srgba8(255 ,199 ,162 ) ); + m_colors08.add_color(0.28, agg::srgba8(255 ,175 ,156 ) ); + m_colors08.add_color(0.42, agg::srgba8(255 ,151 ,151 ) ); + m_colors08.add_color(0.56, agg::srgba8(255 ,127 ,145 ) ); + m_colors08.add_color(0.70, agg::srgba8(255 ,104 ,140 ) ); + m_colors08.add_color(0.84, agg::srgba8(255 ,80 ,133 ) ); + m_colors08.add_color(1.00, agg::srgba8(255 ,56 ,128 ) ); + m_colors08.build_lut(); + + // 9 colors gradient + m_colors09.remove_all(); + m_colors09.add_color(0.000, agg::srgba8(255 ,4 ,163 ) ); + m_colors09.add_color(0.125, agg::srgba8(255 ,4 ,109 ) ); + m_colors09.add_color(0.250, agg::srgba8(255 ,4 ,46 ) ); + m_colors09.add_color(0.375, agg::srgba8(255 ,75 ,75 ) ); + m_colors09.add_color(0.500, agg::srgba8(255 ,120 ,83 ) ); + m_colors09.add_color(0.625, agg::srgba8(255 ,143 ,83 ) ); + m_colors09.add_color(0.750, agg::srgba8(255 ,180 ,83 ) ); + m_colors09.add_color(0.875, agg::srgba8(255 ,209 ,83 ) ); + m_colors09.add_color(1.000, agg::srgba8(255 ,246 ,83 ) ); + m_colors09.build_lut(); + + // 10 colors gradient + m_colors10.remove_all(); + m_colors10.add_color(0.00, agg::srgba8(255 ,0 ,0 ) ); + m_colors10.add_color(0.11, agg::srgba8(255 ,198 ,198 ) ); + m_colors10.add_color(0.22, agg::srgba8(255 ,255 ,0 ) ); + m_colors10.add_color(0.33, agg::srgba8(255 ,255 ,226 ) ); + m_colors10.add_color(0.44, agg::srgba8(85 ,85 ,255 ) ); + m_colors10.add_color(0.55, agg::srgba8(226 ,226 ,255 ) ); + m_colors10.add_color(0.66, agg::srgba8(28 ,255 ,28 ) ); + m_colors10.add_color(0.77, agg::srgba8(226 ,255 ,226 ) ); + m_colors10.add_color(0.88, agg::srgba8(255 ,72 ,255 ) ); + m_colors10.add_color(1.00, agg::srgba8(255 ,227 ,255 ) ); + m_colors10.build_lut(); + + // 11 colors gradient + m_gamma = 1.8; + + m_colors11.remove_all(); + m_colors11.add_color(0.0, agg::srgba8::from_wavelength(380, m_gamma ) ); + m_colors11.add_color(0.1, agg::srgba8::from_wavelength(420, m_gamma ) ); + m_colors11.add_color(0.2, agg::srgba8::from_wavelength(460, m_gamma ) ); + m_colors11.add_color(0.3, agg::srgba8::from_wavelength(500, m_gamma ) ); + m_colors11.add_color(0.4, agg::srgba8::from_wavelength(540, m_gamma ) ); + m_colors11.add_color(0.5, agg::srgba8::from_wavelength(580, m_gamma ) ); + m_colors11.add_color(0.6, agg::srgba8::from_wavelength(620, m_gamma ) ); + m_colors11.add_color(0.7, agg::srgba8::from_wavelength(660, m_gamma ) ); + m_colors11.add_color(0.8, agg::srgba8::from_wavelength(700, m_gamma ) ); + m_colors11.add_color(0.9, agg::srgba8::from_wavelength(740, m_gamma ) ); + m_colors11.add_color(1.0, agg::srgba8::from_wavelength(780, m_gamma ) ); + m_colors11.build_lut(); + + } + + + void draw_text(double x, double y, const char* str) + { + pixfmt pf(rbuf_window()); + agg::renderer_base rb(pf); + agg::renderer_scanline_aa_solid > ren(rb); + + agg::gsv_text txt; + agg::conv_stroke 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 + void perform_rendering(VertexSource& vs, agg::path_storage& contour) + { + typedef agg::renderer_base ren_base; + + pixfmt pf(rbuf_window()); + ren_base rb(pf); + agg::renderer_scanline_aa_solid > rs(rb); + + double x1,y1,x2,y2; + + if (agg::bounding_rect_single(vs ,0 ,&x1 ,&y1 ,&x2 ,&y2 )) + { + // Init Basic Transformations + double scale = (width() - 120 ) / (x2 - x1 ); + + if (scale > (height() - 120 ) / (y2 - y1 ) ) + { + scale = (height() - 120 ) / (y2 - y1 ); + } + + agg::trans_affine mtx; + mtx *= agg::trans_affine_translation(-x1, -y1); + mtx *= agg::trans_affine_scaling(scale, scale); + + agg::conv_transform t1(vs, mtx); + + agg::trans_affine_translation tat(100, 105); + + // Init perspective control + double px1 = x1 ,py1 = y1 ,px2 = x2 ,py2 = y2; + + mtx.transform(&px1 ,&py1 ); + mtx.transform(&px2 ,&py2 ); + + if (m_init) + { + m_persp.xn(0) = px1; + m_persp.yn(0) = py1; + m_persp.xn(1) = px2; + m_persp.yn(1) = py1; + m_persp.xn(2) = px2; + m_persp.yn(2) = py2; + m_persp.xn(3) = px1; + m_persp.yn(3) = py2; + + tat.transform(&m_persp.xn(0) ,&m_persp.yn(0) ); + tat.transform(&m_persp.xn(1) ,&m_persp.yn(1) ); + tat.transform(&m_persp.xn(2) ,&m_persp.yn(2) ); + tat.transform(&m_persp.xn(3) ,&m_persp.yn(3) ); + + m_init = false; + + } + + // Add Perspective Transformation + agg::trans_perspective trpp(px1, py1, px2, py2, m_persp.polygon()); + agg::trans_perspective trpg(m_persp.polygon(), px1, py1, px2, py2); + + if (!trpp.is_valid()) + { + return; + } + + if (!trpg.is_valid()) + { + return; + } + + typedef agg::conv_transform,agg::trans_perspective> t2_type; + + t2_type t2(t1, trpp); + + // Create Path + agg::path_storage path; + path.concat_path(t1 ); + + // Color function + color_func_type* cfunction = NULL; + + if ((int)m_clrs.value() == 2 ) + { + cfunction = &m_colors02; + } + + if ((int)m_clrs.value() == 3 ) + { + cfunction = &m_colors03; + } + + if ((int)m_clrs.value() == 4 ) + { + cfunction = &m_colors04; + } + + if ((int)m_clrs.value() == 5 ) + { + cfunction = &m_colors05; + } + + if ((int)m_clrs.value() == 6 ) + { + cfunction = &m_colors06; + } + + if ((int)m_clrs.value() == 7 ) + { + cfunction = &m_colors07; + } + + if ((int)m_clrs.value() == 8 ) + { + cfunction = &m_colors08; + } + + if ((int)m_clrs.value() == 9 ) + { + cfunction = &m_colors09; + } + + if ((int)m_clrs.value() == 10 ) + { + cfunction = &m_colors10; + } + + if (!cfunction) + { + cfunction = &m_colors11; + } + + // Render + double d1 = 0; + double d2 = 100; + + switch(m_gradient.cur_item()) + { + // contour {..} + case 0: + case 1: + { + agg::gradient_contour gradient_func; + + gradient_func.frame(0 ); + gradient_func.d1(m_c1.value()); + gradient_func.d2(m_c2.value()); + + switch(m_gradient.cur_item()) + { + case 0: + if (!gradient_func.contour_create(&contour )) + { + return; + } + break; + case 1: + if (!gradient_func.contour_create(&path )) + { + return; + } + break; + + } + + d1 = m_d1.value(); + d2 = m_d2.value(); + + agg::span_interpolator_trans span_interpolator(trpg ); + + if (m_refl.status()) + { + agg::gradient_reflect_adaptor func_reflect(gradient_func); + + typedef agg::span_gradient, + agg::gradient_reflect_adaptor, + color_func_type> span_gradient_type; + + span_gradient_type span_gradient( + span_interpolator, + func_reflect, + *cfunction, + d1, d2); + + m_ras.reset(); + m_ras.add_path(t2 ); + + agg::render_scanlines_aa(m_ras, m_sl, rb, m_alloc, span_gradient); + + } + else + { + typedef agg::span_gradient, + agg::gradient_contour, + color_func_type> span_gradient_type; + + span_gradient_type span_gradient( + span_interpolator, + gradient_func, + *cfunction, + d1, d2); + + m_ras.reset(); + m_ras.add_path(t2 ); + + agg::render_scanlines_aa(m_ras, m_sl, rb, m_alloc, span_gradient); + } + } + break; + + // assymetric conic + case 2: + { + gradient_conic_angle gradient_func; + + agg::trans_affine_translation gmt(270 ,300); + gmt.invert(); + + agg::span_interpolator_linear<> span_interpolator(gmt); + + typedef agg::span_gradient, + gradient_conic_angle, + color_func_type> span_gradient_type; + + span_gradient_type span_gradient( + span_interpolator, + gradient_func, + *cfunction, + d1, d2); + + m_ras.reset(); + m_ras.add_path(t2 ); + + agg::render_scanlines_aa(m_ras, m_sl, rb, m_alloc, span_gradient); + + } + break; + + // Flat fill + default: + m_ras.reset(); + m_ras.add_path(t2 ); + rs.color(agg::rgba(0, 0.6, 0, 0.5)); + agg::render_scanlines(m_ras, m_sl, rs); + + } + + // Stroke + if (m_stroke.status()) + { + agg::gradient_image gradient_func; + + void* bitmap = gradient_func.image_create(64 ,64 ); + + if (bitmap) + { + memmove(bitmap, agg::puzzle, 64 * 64 * 4 ); + + agg::conv_stroke stroke(t2 ); + stroke.width(10.0 ); + + agg::span_interpolator_trans span_interpolator(trpg ); + + typedef agg::one_color_function color_func_type; + typedef agg::span_gradient, + agg::gradient_image, + const color_func_type> span_gradient_type; + + span_gradient_type span_gradient( + span_interpolator, + gradient_func, + gradient_func.color_function(), + d1, d2); + + m_ras.reset(); + m_ras.add_path(stroke ); + + agg::render_scanlines_aa(m_ras, m_sl, rb, m_alloc, span_gradient); + + } + + } + + } + + } + + unsigned render() + { + agg::path_storage star; + + star.move_to(12.0 ,40.0 ); + star.line_to(52.0 ,40.0 ); + star.line_to(72.0 ,6.0 ); + star.line_to(92.0 ,40.0 ); + star.line_to(132.0 ,40.0 ); + star.line_to(112.0 ,76.0 ); + star.line_to(132.0 ,112.0 ); + star.line_to(92.0 ,112.0 ); + star.line_to(72.0 ,148.0 ); + star.line_to(52.0 ,112.0 ); + star.line_to(12.0 ,112.0 ); + star.line_to(32.0 ,76.0 ); + star.close_polygon(); + + switch(m_polygons.cur_item()) + { + // Simple path + case 0: + { + perform_rendering(star ,star ); + + } + break; + + // Great Britain + case 1: + { + agg::path_storage gb_poly; + make_gb_poly(gb_poly); + perform_rendering(gb_poly ,star ); + + } + break; + + // Spiral + case 2: + { + spiral sp(0, 0, 10, 150, 30, 0.0); + agg::conv_stroke stroke(sp); + stroke.width(22.0); + perform_rendering(stroke ,star ); + + } + break; + + // Glyph + case 3: + { + 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::conv_curve curve(glyph); + curve.approximation_scale(10 ); + + perform_rendering(curve ,star ); + + } + break; + + } + + return 0; + } + + virtual void on_draw() + { + typedef agg::renderer_base base_ren_type; + + pixfmt 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_persp); + agg::render_ctrl(m_ras, m_sl, ren_base, m_polygons); + agg::render_ctrl(m_ras, m_sl, ren_base, m_gradient ); + agg::render_ctrl(m_ras, m_sl, ren_base, m_stroke ); + agg::render_ctrl(m_ras, m_sl, ren_base, m_refl ); + agg::render_ctrl(m_ras, m_sl, ren_base, m_c1 ); + agg::render_ctrl(m_ras, m_sl, ren_base, m_c2 ); + agg::render_ctrl(m_ras, m_sl, ren_base, m_d1 ); + agg::render_ctrl(m_ras, m_sl, ren_base, m_d2 ); + agg::render_ctrl(m_ras, m_sl, ren_base, m_clrs ); + } + + virtual void on_ctrl_change() + { + if (m_last != m_polygons.cur_item()) + { + m_last = m_polygons.cur_item(); + m_init = true; + } + } + + virtual void on_resize(int cx, int cy) + { + m_init = true; + } + +#define BBOX double x1, y1, x2, y2;\ +x1 = m_persp.xn(0 );\ +y1 = m_persp.yn(0 );\ +x2 = m_persp.xn(1 );\ +y2 = m_persp.yn(2 );\ +if (m_persp.yn(1 ) < y1 )\ +{\ + y1 = m_persp.yn(1 );\ +}\ +if (m_persp.xn(2 ) > x2 )\ +{\ + x2 = m_persp.xn(2 );\ +}\ +if (m_persp.xn(3 ) < x1 )\ +{\ + x1 = m_persp.xn(3 );\ +}\ +if (m_persp.yn(3 ) > y2 )\ +{\ + y2 = m_persp.yn(3 );\ +} + +#define ROTATE(a) agg::trans_affine_translation tat(-(x1 + (x2 - x1 ) / 2 ) ,-(y1 + (y2 - y1 ) / 2 ) );\ +tat.transform(&m_persp.xn(0) ,&m_persp.yn(0) );\ +tat.transform(&m_persp.xn(1) ,&m_persp.yn(1) );\ +tat.transform(&m_persp.xn(2) ,&m_persp.yn(2) );\ +tat.transform(&m_persp.xn(3) ,&m_persp.yn(3) );\ +agg::trans_affine_rotation tar(agg::deg2rad(a ) );\ +tar.transform(&m_persp.xn(0) ,&m_persp.yn(0) );\ +tar.transform(&m_persp.xn(1) ,&m_persp.yn(1) );\ +tar.transform(&m_persp.xn(2) ,&m_persp.yn(2) );\ +tar.transform(&m_persp.xn(3) ,&m_persp.yn(3) );\ +agg::trans_affine_translation tt2(x1 + (x2 - x1 ) / 2 ,y1 + (y2 - y1 ) / 2 );\ +tt2.transform(&m_persp.xn(0) ,&m_persp.yn(0) );\ +tt2.transform(&m_persp.xn(1) ,&m_persp.yn(1) );\ +tt2.transform(&m_persp.xn(2) ,&m_persp.yn(2) );\ +tt2.transform(&m_persp.xn(3) ,&m_persp.yn(3) );\ +force_redraw(); + +#define ZOOM(z) agg::trans_affine_translation tat(-(x1 + (x2 - x1 ) / 2 ) ,-(y1 + (y2 - y1 ) / 2 ) );\ +tat.transform(&m_persp.xn(0) ,&m_persp.yn(0) );\ +tat.transform(&m_persp.xn(1) ,&m_persp.yn(1) );\ +tat.transform(&m_persp.xn(2) ,&m_persp.yn(2) );\ +tat.transform(&m_persp.xn(3) ,&m_persp.yn(3) );\ +agg::trans_affine_scaling tas(z );\ +tas.transform(&m_persp.xn(0) ,&m_persp.yn(0) );\ +tas.transform(&m_persp.xn(1) ,&m_persp.yn(1) );\ +tas.transform(&m_persp.xn(2) ,&m_persp.yn(2) );\ +tas.transform(&m_persp.xn(3) ,&m_persp.yn(3) );\ +agg::trans_affine_translation tt2(x1 + (x2 - x1 ) / 2 ,y1 + (y2 - y1 ) / 2 );\ +tt2.transform(&m_persp.xn(0) ,&m_persp.yn(0) );\ +tt2.transform(&m_persp.xn(1) ,&m_persp.yn(1) );\ +tt2.transform(&m_persp.xn(2) ,&m_persp.yn(2) );\ +tt2.transform(&m_persp.xn(3) ,&m_persp.yn(3) );\ +force_redraw(); + + virtual void on_key(int x, int y, unsigned key, unsigned flags ) + { + if (key == agg::key_kp_plus ) + { + BBOX + ROTATE(-angle) + } + + if (key == agg::key_kp_minus ) + { + BBOX + ROTATE(angle) + } + + if (key == agg::key_page_up ) + { + BBOX + ZOOM(zoom_up) + } + + if (key == agg::key_page_down ) + { + BBOX + ZOOM(zoom_down) + } + + if (key == agg::key_f1) + { + message( + "Here are some more gradient functions. Firstly the Contour gradient, makes\n" + "color transitions from shape defined by an arbitrary (in fact any) path.\n" + "It computes so called Distance Transform (DT) from image produced by only\n" + "stroking the path, which is then the source of color level in the underlying\n" + "gradient function. Contour gradient can be used in two forms. One is to define \n" + "shape for contour different from shape of object being drawn. Second is to\n" + "use the same shape for contour and for drawing (AutoContour).\n\n" + + "Assymetric conic gradient (also called angle) is the same as conic, but the ray\n" + "of light with color transitions going counter clockwise travels whole circle\n" + "instead of just half (as with conic).\n\n" + + "Bitmap gradient is very similar to pattern fill, but works in the framework of\n" + "gradient functions interfaces. Because of that all interpolator transformations\n" + "from gradient span generator can be applied to this kind of fill.\n\n" + + "How to play with:\n\n" + + "Try to fiddle with C1,C2 & D1,D2 parameters to see, how interestingly\n" + "the gradient transitions changes (each time a new DT is computed).\n" + "DT is reused when the color ramp changes.\n\n" + + "Use +/- keys to Rotate polygon\n" + "Use PgUp/PdDn keys to Zoom polygon\n\n" + + "Note: F2 key saves current 'screenshot' file in this demo's directory. " ); + + } + + } + +}; + + + +int agg_main(int argc, char* argv[]) +{ + the_application app(pix_format, flip_y); + app.caption("AGG Example. More gradients: Contour, Bitmap & Assymetric Conic (F1-Help)"); + + if(app.init(520, 520, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + diff --git a/examples/graph_test.cpp b/examples/graph_test.cpp new file mode 100644 index 0000000..cbabc50 --- /dev/null +++ b/examples/graph_test.cpp @@ -0,0 +1,925 @@ +#include +#include +#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 base_renderer; +typedef agg::renderer_primitives primitives_renderer; + +typedef agg::renderer_scanline_aa_solid solid_renderer; +typedef agg::renderer_scanline_bin_solid draft_renderer; + +typedef agg::gradient_radial_d gradient_function; +typedef agg::span_interpolator_linear<> interpolator; +typedef agg::pod_auto_array color_array_type; +typedef agg::span_gradient gradient_span_gen; +typedef agg::span_allocator gradient_span_alloc; + +typedef agg::renderer_scanline_aa gradient_renderer; + +typedef agg::rasterizer_scanline_aa<> scanline_rasterizer; +typedef agg::rasterizer_outline 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 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 struct stroke_draft_arrow +{ + typedef agg::conv_marker_adaptor stroke_type; + typedef agg::conv_marker marker_type; + typedef agg::conv_concat 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 struct stroke_fine_simple +{ + typedef agg::conv_stroke 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 struct stroke_fine_arrow +{ + typedef agg::conv_stroke stroke_type; + typedef agg::conv_marker marker_type; + typedef agg::conv_concat 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 struct dash_stroke_draft_simple +{ + typedef agg::conv_dash 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 struct dash_stroke_draft_arrow +{ + typedef agg::conv_dash dash_type; + typedef agg::conv_marker marker_type; + typedef agg::conv_concat 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 struct dash_stroke_fine_simple +{ + typedef agg::conv_dash dash_type; + typedef agg::conv_stroke 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 struct dash_stroke_fine_arrow +{ + typedef agg::conv_dash dash_type; + typedef agg::conv_stroke stroke_type; + typedef agg::conv_marker marker_type; + typedef agg::conv_concat 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 m_type; + agg::slider_ctrl m_width; + agg::cbox_ctrl m_benchmark; + agg::cbox_ctrl m_draw_nodes; + agg::cbox_ctrl m_draw_edges; + agg::cbox_ctrl m_draft; + agg::cbox_ctrl 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 + 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 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 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 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 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 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 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; +} + + diff --git a/examples/idea.cpp b/examples/idea.cpp new file mode 100644 index 0000000..6ac4acb --- /dev/null +++ b/examples/idea.cpp @@ -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 m_rotate; + agg::cbox_ctrl m_even_odd; + agg::cbox_ctrl m_draft; + agg::cbox_ctrl m_roundoff; + agg::slider_ctrl 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 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 fill(g_path, mtx); + agg::conv_transform + < + agg::conv_transform, + trans_roundoff + > + fill_roundoff(fill, roundoff); + + agg::conv_stroke + < + agg::conv_transform + > + stroke(fill); + + agg::conv_stroke + < + agg::conv_transform + < + agg::conv_transform, + 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; +} + + diff --git a/examples/image1.cpp b/examples/image1.cpp new file mode 100644 index 0000000..cb7c4b6 --- /dev/null +++ b/examples/image1.cpp @@ -0,0 +1,214 @@ +#include +#include +#include +#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 m_angle; + agg::slider_ctrl 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 renderer_base; + typedef agg::renderer_base 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 sa; + + typedef agg::span_interpolator_linear<> interpolator_type; + interpolator_type interpolator(img_mtx); + + typedef agg::image_accessor_clip 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 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 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 span_gen_type; + agg::image_filter filter; + span_gen_type sg(img_src, interpolator, filter); + //------------------------------------------ +*/ +/* + // Version with arbitrary filter + //------------------------------------------ + typedef agg::span_image_filter_rgb span_gen_type; + agg::image_filter 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 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 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 >::agg::span_image_filter_gray_bilinear >(class agg::span_interpolator_linear &,const class agg::row_ptr_cache &,const struct agg::sgray8 &,struct agg::order_bgra &)' : + +cannot convert parameter 1 from + +'class agg::span_allocator' to +'class agg::span_interpolator_linear &' +*/ diff --git a/examples/image_alpha.cpp b/examples/image_alpha.cpp new file mode 100644 index 0000000..523199c --- /dev/null +++ b/examples/image_alpha.cpp @@ -0,0 +1,251 @@ +#include +#include +#include +#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 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 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 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 img_source_type; + typedef agg::span_interpolator_linear<> interpolator_type; + typedef agg::span_image_filter_rgb_bilinear span_gen; + typedef agg::span_converter 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 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; +} + + diff --git a/examples/image_filters.cpp b/examples/image_filters.cpp new file mode 100644 index 0000000..4c71ac1 --- /dev/null +++ b/examples/image_filters.cpp @@ -0,0 +1,428 @@ +#include +#include +#include +#include +#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 renderer_base; + typedef agg::renderer_base renderer_base_pre; + + agg::slider_ctrl m_radius; + agg::slider_ctrl m_step; + agg::rbox_ctrl m_filters; + agg::cbox_ctrl m_normalize; + agg::cbox_ctrl m_run; + agg::cbox_ctrl m_single_step; + agg::cbox_ctrl 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 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 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 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 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 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 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 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 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; +} + + diff --git a/examples/image_filters2.cpp b/examples/image_filters2.cpp new file mode 100644 index 0000000..242753a --- /dev/null +++ b/examples/image_filters2.cpp @@ -0,0 +1,273 @@ +#include +#include +#include +#include +#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 renderer_base; + typedef agg::renderer_base renderer_base_pre; + + agg::slider_ctrl m_radius; + agg::rbox_ctrl m_filters; + agg::cbox_ctrl 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 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 sa; + + typedef agg::image_accessor_clone 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 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 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 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; +} + + diff --git a/examples/image_fltr_graph.cpp b/examples/image_fltr_graph.cpp new file mode 100644 index 0000000..5d13f3c --- /dev/null +++ b/examples/image_fltr_graph.cpp @@ -0,0 +1,315 @@ +#include +#include +#include +#include +#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 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 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 m_radius; + agg::cbox_ctrl m_bilinear; + agg::cbox_ctrl m_bicubic; + agg::cbox_ctrl m_spline16; + agg::cbox_ctrl m_spline36; + agg::cbox_ctrl m_hanning; + agg::cbox_ctrl m_hamming; + agg::cbox_ctrl m_hermite; + agg::cbox_ctrl m_kaiser; + agg::cbox_ctrl m_quadric; + agg::cbox_ctrl m_catrom; + agg::cbox_ctrl m_gaussian; + agg::cbox_ctrl m_bessel; + agg::cbox_ctrl m_mitchell; + agg::cbox_ctrl m_sinc; + agg::cbox_ctrl m_lanczos; + agg::cbox_ctrl m_blackman; + agg::cbox_ctrl* m_filters[32]; + + image_filter_const_radius_adaptor m_filter_bilinear; + image_filter_const_radius_adaptor m_filter_bicubic; + image_filter_const_radius_adaptor m_filter_spline16; + image_filter_const_radius_adaptor m_filter_spline36; + image_filter_const_radius_adaptor m_filter_hanning; + image_filter_const_radius_adaptor m_filter_hamming; + image_filter_const_radius_adaptor m_filter_hermite; + image_filter_const_radius_adaptor m_filter_kaiser; + image_filter_const_radius_adaptor m_filter_quadric; + image_filter_const_radius_adaptor m_filter_catrom; + image_filter_const_radius_adaptor m_filter_gaussian; + image_filter_const_radius_adaptor m_filter_bessel; + image_filter_const_radius_adaptor m_filter_mitchell; + image_filter_variable_radius_adaptor m_filter_sinc; + image_filter_variable_radius_adaptor m_filter_lanczos; + image_filter_variable_radius_adaptor 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 renderer_base; + typedef agg::renderer_scanline_aa_solid 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 pl(p); + agg::conv_transform > 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; +} + + diff --git a/examples/image_perspective.cpp b/examples/image_perspective.cpp new file mode 100644 index 0000000..26755eb --- /dev/null +++ b/examples/image_perspective.cpp @@ -0,0 +1,329 @@ +#include +#include +#include +#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 renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_solid; + typedef agg::renderer_base renderer_base_pre; + + agg::interactive_polygon m_quad; + agg::rbox_ctrl 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 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 img_accessor_type; + //img_accessor_type ia(pixf_img); + + //typedef agg::image_accessor_clip img_accessor_type; + //img_accessor_type ia(pixf_img, agg::rgba(1,1,1)); + + typedef agg::image_accessor_clone 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 interpolator_type; + interpolator_type interpolator(tr); + + typedef agg::span_image_filter_rgba_nn 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 interpolator_type; + interpolator_type interpolator(tr); + + typedef agg::span_image_filter_rgba_2x2 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 interpolator_type; + //typedef agg::span_subdiv_adaptor subdiv_adaptor_type; + //interpolator_type interpolator(tr); + //subdiv_adaptor_type subdiv_adaptor(interpolator); + // + //typedef agg::span_image_filter_rgba_2x2 span_gen_type; + //span_gen_type sg(ia, subdiv_adaptor, filter); + //----------------------- + + // Direct calculations of the coordinates + //----------------------- + typedef agg::span_interpolator_trans interpolator_type; + interpolator_type interpolator(tr); + typedef agg::span_image_filter_rgba_2x2 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 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; +} + + + + + + diff --git a/examples/image_resample.cpp b/examples/image_resample.cpp new file mode 100644 index 0000000..3ea9684 --- /dev/null +++ b/examples/image_resample.cpp @@ -0,0 +1,371 @@ +#include +#include +#include +#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 renderer_base; +typedef agg::renderer_base renderer_base_pre; +typedef agg::renderer_scanline_aa_solid renderer_solid; + +class the_application : public agg::platform_support +{ +public: + agg::interactive_polygon m_quad; + agg::rbox_ctrl m_trans_type; + agg::slider_ctrl m_blur; + agg::slider_ctrl 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 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 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 interpolator_type; + interpolator_type interpolator(tr); + + typedef image_filter_2x2_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 interpolator_type; + typedef image_resample_affine_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 interpolator_type; + interpolator_type interpolator(tr); + + typedef image_filter_2x2_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 interpolator_type; + interpolator_type interpolator(tr); + + typedef image_filter_2x2_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 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 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 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 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 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; +} + + + + + + diff --git a/examples/image_transforms.cpp b/examples/image_transforms.cpp new file mode 100644 index 0000000..98ce6fe --- /dev/null +++ b/examples/image_transforms.cpp @@ -0,0 +1,454 @@ +#include +#include +#include +#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 m_polygon_angle; + agg::slider_ctrl m_polygon_scale; + + agg::slider_ctrl m_image_angle; + agg::slider_ctrl m_image_scale; + + agg::cbox_ctrl m_rotate_polygon; + agg::cbox_ctrl m_rotate_image; + + agg::rbox_ctrl 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 renderer_base; + typedef agg::renderer_scanline_aa_solid 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 sa; + + // "hardcoded" bilinear filter + //------------------------------------------ + typedef agg::span_image_filter_rgba_bilinear_clip 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 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 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 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; +} + + diff --git a/examples/interactive_polygon.cpp b/examples/interactive_polygon.cpp new file mode 100644 index 0000000..ae2f695 --- /dev/null +++ b/examples/interactive_polygon.cpp @@ -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; + } +} + diff --git a/examples/interactive_polygon.h b/examples/interactive_polygon.h new file mode 100644 index 0000000..8e4befe --- /dev/null +++ b/examples/interactive_polygon.h @@ -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 m_polygon; + unsigned m_num_points; + int m_node; + int m_edge; + simple_polygon_vertex_source m_vs; + conv_stroke m_stroke; + ellipse m_ellipse; + double m_point_radius; + unsigned m_status; + double m_dx; + double m_dy; + }; + + +} + +#endif + diff --git a/examples/line_patterns.cpp b/examples/line_patterns.cpp new file mode 100644 index 0000000..bdfb1ad --- /dev/null +++ b/examples/line_patterns.cpp @@ -0,0 +1,334 @@ +#include +#include +#include +#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 m_curve1; + agg::bezier_ctrl m_curve2; + agg::bezier_ctrl m_curve3; + agg::bezier_ctrl m_curve4; + agg::bezier_ctrl m_curve5; + agg::bezier_ctrl m_curve6; + agg::bezier_ctrl m_curve7; + agg::bezier_ctrl m_curve8; + agg::bezier_ctrl m_curve9; + agg::slider_ctrl m_scale_x; + agg::slider_ctrl m_start_x; + +public: + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid 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 + 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 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 > pattern_type; + typedef agg::renderer_base base_ren_type; + typedef agg::renderer_outline_image renderer_type; + typedef agg::rasterizer_outline_aa 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; +} + + diff --git a/examples/line_patterns_clip.cpp b/examples/line_patterns_clip.cpp new file mode 100644 index 0000000..5e9bcc2 --- /dev/null +++ b/examples/line_patterns_clip.cpp @@ -0,0 +1,353 @@ +#include +#include +#include +#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 m_line1; + agg::slider_ctrl m_scale_x; + agg::slider_ctrl m_start_x; + agg::trans_affine m_scale; + +public: + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid 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_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 + void draw_polyline(Rasterizer& ras, + Renderer& ren, + const double* polyline, + int num_points) + { + agg::poly_plain_adaptor vs(polyline, num_points, m_line1.close()); + agg::conv_transform > 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 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 > pattern_type; + typedef agg::renderer_base base_ren_type; + typedef agg::renderer_outline_image renderer_img_type; + typedef agg::rasterizer_outline_aa rasterizer_img_type; + + typedef agg::renderer_outline_aa renderer_line_type; + typedef agg::rasterizer_outline_aa 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 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; +} + + diff --git a/examples/line_thickness.cpp b/examples/line_thickness.cpp new file mode 100644 index 0000000..4aa0eee --- /dev/null +++ b/examples/line_thickness.cpp @@ -0,0 +1,145 @@ +#include +#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 m_slider1; + agg::slider_ctrl m_slider2; + agg::cbox_ctrl m_cbox1; + agg::cbox_ctrl 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 + 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 ren(pf); + agg::scanline_u8 sl; + agg::rasterizer_scanline_aa<> ras; + agg::path_storage ps; + agg::conv_stroke 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 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; +} + + diff --git a/examples/lion.cpp b/examples/lion.cpp new file mode 100644 index 0000000..7cd7851 --- /dev/null +++ b/examples/lion.cpp @@ -0,0 +1,175 @@ +#include +#include +#include +#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 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 m_alpha_slider; + +public: + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid 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 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; +} + + + + + + diff --git a/examples/lion_lens.cpp b/examples/lion_lens.cpp new file mode 100644 index 0000000..4ce8193 --- /dev/null +++ b/examples/lion_lens.cpp @@ -0,0 +1,204 @@ +#include +#include +#include +#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 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 m_magn_slider; + agg::slider_ctrl m_radius_slider; + +public: + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid 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 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; +} + + + + + + diff --git a/examples/lion_outline.cpp b/examples/lion_outline.cpp new file mode 100644 index 0000000..7528f78 --- /dev/null +++ b/examples/lion_outline.cpp @@ -0,0 +1,192 @@ +#include +#include +#include +#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 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 m_width_slider; + agg::cbox_ctrl 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 renderer_base; + typedef agg::renderer_scanline_aa_solid 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 stroke(g_path); + stroke.width(m_width_slider.value()); + stroke.line_join(agg::round_join); + agg::conv_transform > 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_type; + typedef agg::rasterizer_outline_aa 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 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; +} + + + + + + diff --git a/examples/macosx_carbon/Makefile b/examples/macosx_carbon/Makefile new file mode 100644 index 0000000..ebad632 --- /dev/null +++ b/examples/macosx_carbon/Makefile @@ -0,0 +1,280 @@ +AGGLIBS= -lagg -framework Carbon -framework QuickTime +AGGCXXFLAGS = -bind_at_load -O3 -I/Developer/Headers/FlatCarbon +CXX = g++ +C = gcc +#CXX = icc +LIB = ar cr -s + +PLATFORM=mac + +PLATFORMSOURCES=../../src/platform/$(PLATFORM)/agg_platform_support.o ../../src/platform/$(PLATFORM)/agg_mac_pmap.o + +CXXFLAGS= $(AGGCXXFLAGS) -I../../include \ +-L../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm + +all: + 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 gamma_correction + make gamma_ctrl + make gouraud + 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 line_patterns + make mol_view + +aa_demo: ../aa_demo.o $(PLATFORMSOURCES) aa_demo.app + $(CXX) $(CXXFLAGS) ../aa_demo.o $(PLATFORMSOURCES) -o aa_demo.app/Contents/MacOS/aa_demo $(LIBS) + +aa_test: ../aa_test.o $(PLATFORMSOURCES) aa_test.app + $(CXX) $(CXXFLAGS) ../aa_test.o $(PLATFORMSOURCES) -o aa_test.app/Contents/MacOS/aa_test $(LIBS) + +alpha_gradient: ../alpha_gradient.o $(PLATFORMSOURCES) alpha_gradient.app + $(CXX) $(CXXFLAGS) ../alpha_gradient.o $(PLATFORMSOURCES) -o alpha_gradient.app/Contents/MacOS/alpha_gradient $(LIBS) + +alpha_mask: ../alpha_mask.o ../parse_lion.o $(PLATFORMSOURCES) alpha_mask.app + $(CXX) $(CXXFLAGS) ../alpha_mask.o ../parse_lion.o $(PLATFORMSOURCES) -o alpha_mask.app/Contents/MacOS/alpha_mask $(LIBS) + +alpha_mask2: ../alpha_mask2.o ../parse_lion.o $(PLATFORMSOURCES) alpha_mask2.app + $(CXX) $(CXXFLAGS) ../alpha_mask2.o ../parse_lion.o $(PLATFORMSOURCES) -o alpha_mask2.app/Contents/MacOS/alpha_mask2 $(LIBS) + +alpha_mask3: ../alpha_mask3.o ../make_arrows.o ../make_gb_poly.o $(PLATFORMSOURCES) alpha_mask3.app + $(CXX) $(CXXFLAGS) ../alpha_mask3.o ../make_arrows.o ../make_gb_poly.o $(PLATFORMSOURCES) -o alpha_mask3.app/Contents/MacOS/alpha_mask3 $(LIBS) + +bezier_div: ../bezier_div.o ../interactive_polygon.o $(PLATFORMSOURCES) bezier_div.app + $(CXX) $(CXXFLAGS) ../bezier_div.o ../interactive_polygon.o $(PLATFORMSOURCES) -o bezier_div.app/Contents/MacOS/bezier_div $(LIBS) + +blur: ../blur.o $(PLATFORMSOURCES) blur.app + $(CXX) $(CXXFLAGS) ../blur.o $(PLATFORMSOURCES) -o blur.app/Contents/MacOS/blur $(LIBS) + +blend_color: ../blend_color.o $(PLATFORMSOURCES) blend_color.app + $(CXX) $(CXXFLAGS) ../blend_color.o $(PLATFORMSOURCES) -o blend_color.app/Contents/MacOS/blend_color $(LIBS) + +bspline: ../bspline.o ../interactive_polygon.o $(PLATFORMSOURCES) bspline.app + $(CXX) $(CXXFLAGS) ../bspline.o ../interactive_polygon.o $(PLATFORMSOURCES) -o bspline.app/Contents/MacOS/bspline $(LIBS) + +circles: ../circles.o $(PLATFORMSOURCES) circles.app + $(CXX) $(CXXFLAGS) ../circles.o $(PLATFORMSOURCES) -o circles.app/Contents/MacOS/circles $(LIBS) + +component_rendering: ../component_rendering.o $(PLATFORMSOURCES) component_rendering.app + $(CXX) $(CXXFLAGS) ../component_rendering.o $(PLATFORMSOURCES) -o component_rendering.app/Contents/MacOS/component_rendering $(LIBS) + +compositing: ../compositing.o $(PLATFORMSOURCES) compositing.bmp compositing.app + cp compositing.bmp compositing.app/Contents/MacOS/compositing.bmp + $(CXX) $(CXXFLAGS) ../compositing.o $(PLATFORMSOURCES) -o compositing.app/Contents/MacOS/compositing $(LIBS) + +conv_contour: ../conv_contour.o $(PLATFORMSOURCES) conv_contour.app + $(CXX) $(CXXFLAGS) ../conv_contour.o $(PLATFORMSOURCES) -o conv_contour.app/Contents/MacOS/conv_contour $(LIBS) + +conv_dash_marker: ../conv_dash_marker.o $(PLATFORMSOURCES) conv_dash_marker.app + $(CXX) $(CXXFLAGS) ../conv_dash_marker.o $(PLATFORMSOURCES) -o conv_dash_marker.app/Contents/MacOS/conv_dash_marker $(LIBS) + +conv_stroke: ../conv_stroke.o $(PLATFORMSOURCES) conv_stroke.app + $(CXX) $(CXXFLAGS) ../conv_stroke.o $(PLATFORMSOURCES) -o conv_stroke.app/Contents/MacOS/conv_stroke $(LIBS) + +distortions: ../distortions.o $(PLATFORMSOURCES) spheres.bmp distortions.app + cp spheres.bmp distortions.app/Contents/MacOS/spheres.bmp + $(CXX) $(CXXFLAGS) ../distortions.o $(PLATFORMSOURCES) -o distortions.app/Contents/MacOS/distortions $(LIBS) + +gamma_correction: ../gamma_correction.o $(PLATFORMSOURCES) gamma_correction.app + $(CXX) $(CXXFLAGS) ../gamma_correction.o $(PLATFORMSOURCES) -o gamma_correction.app/Contents/MacOS/gamma_correction $(LIBS) + +gamma_ctrl: ../gamma_ctrl.o $(PLATFORMSOURCES) gamma_ctrl.app + $(CXX) $(CXXFLAGS) ../gamma_ctrl.o $(PLATFORMSOURCES) -o gamma_ctrl.app/Contents/MacOS/gamma_ctrl $(LIBS) + +gouraud: ../gouraud.o $(PLATFORMSOURCES) gouraud.app + $(CXX) $(CXXFLAGS) ../gouraud.o $(PLATFORMSOURCES) -o gouraud.app/Contents/MacOS/gouraud $(LIBS) + +gradient_focal: ../gradient_focal.o $(PLATFORMSOURCES) gradient_focal.app + $(CXX) $(CXXFLAGS) ../gradient_focal.o $(PLATFORMSOURCES) -o gradient_focal.app/Contents/MacOS/gradient_focal $(LIBS) + +gradients: ../gradients.o $(PLATFORMSOURCES) gradients.app + $(CXX) $(CXXFLAGS) ../gradients.o $(PLATFORMSOURCES) -o gradients.app/Contents/MacOS/gradients $(LIBS) + +graph_test: ../graph_test.o $(PLATFORMSOURCES) graph_test.app + $(CXX) $(CXXFLAGS) ../graph_test.o $(PLATFORMSOURCES) -o graph_test.app/Contents/MacOS/graph_test $(LIBS) + +idea: ../idea.o $(PLATFORMSOURCES) idea.app + $(CXX) $(CXXFLAGS) ../idea.o $(PLATFORMSOURCES) -o idea.app/Contents/MacOS/idea $(LIBS) + +image_alpha: ../image_alpha.o $(PLATFORMSOURCES) spheres.bmp image_alpha.app + cp spheres.bmp image_alpha.app/Contents/MacOS/spheres.bmp + $(CXX) $(CXXFLAGS) ../image_alpha.o $(PLATFORMSOURCES) -o image_alpha.app/Contents/MacOS/image_alpha $(LIBS) + +image_filters: ../image_filters.o $(PLATFORMSOURCES) spheres.bmp image_filters.app + cp spheres.bmp image_filters.app/Contents/MacOS/spheres.bmp + $(CXX) $(CXXFLAGS) ../image_filters.o $(PLATFORMSOURCES) -o image_filters.app/Contents/MacOS/image_filters $(LIBS) + +image_filters2: ../image_filters2.o $(PLATFORMSOURCES) spheres.bmp image_filters2.app + cp spheres.bmp image_filters2.app/Contents/MacOS/spheres.bmp + $(CXX) $(CXXFLAGS) ../image_filters2.o $(PLATFORMSOURCES) -o image_filters2.app/Contents/MacOS/image_filters2 $(LIBS) + +image_fltr_graph: ../image_fltr_graph.o $(PLATFORMSOURCES) spheres.bmp image_fltr_graph.app + cp spheres.bmp image_fltr_graph.app/Contents/MacOS/spheres.bmp + $(CXX) $(CXXFLAGS) ../image_fltr_graph.o $(PLATFORMSOURCES) -o image_fltr_graph.app/Contents/MacOS/image_fltr_graph $(LIBS) + +image_perspective: ../image_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) spheres.bmp image_perspective.app + cp spheres.bmp image_perspective.app/Contents/MacOS/spheres.bmp + $(CXX) $(CXXFLAGS) ../image_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) -o image_perspective.app/Contents/MacOS/image_perspective $(LIBS) + +image_resample: ../image_resample.o ../interactive_polygon.o $(PLATFORMSOURCES) spheres.bmp image_resample.app + cp spheres.bmp image_resample.app/Contents/MacOS/spheres.bmp + $(CXX) $(CXXFLAGS) ../image_resample.o ../interactive_polygon.o $(PLATFORMSOURCES) -o image_resample.app/Contents/MacOS/image_resample $(LIBS) + +image_transforms: ../image_transforms.o $(PLATFORMSOURCES) spheres.bmp image_transforms.app + cp spheres.bmp image_transforms.app/Contents/MacOS/spheres.bmp + $(CXX) $(CXXFLAGS) ../image_transforms.o $(PLATFORMSOURCES) -o image_transforms.app/Contents/MacOS/image_transforms $(LIBS) + +image1: ../image1.o $(PLATFORMSOURCES) spheres.bmp image1.app + cp spheres.bmp image1.app/Contents/MacOS/spheres.bmp + $(CXX) $(CXXFLAGS) ../image1.o $(PLATFORMSOURCES) -o image1.app/Contents/MacOS/image1 $(LIBS) + +line_patterns: ../line_patterns.o $(PLATFORMSOURCES) 1.bmp 2.bmp 3.bmp 4.bmp 5.bmp 6.bmp 7.bmp 8.bmp 9.bmp line_patterns.app + cp 1.bmp line_patterns.app/Contents/MacOS/1.bmp + cp 2.bmp line_patterns.app/Contents/MacOS/2.bmp + cp 3.bmp line_patterns.app/Contents/MacOS/3.bmp + cp 4.bmp line_patterns.app/Contents/MacOS/4.bmp + cp 5.bmp line_patterns.app/Contents/MacOS/5.bmp + cp 6.bmp line_patterns.app/Contents/MacOS/6.bmp + cp 7.bmp line_patterns.app/Contents/MacOS/7.bmp + cp 8.bmp line_patterns.app/Contents/MacOS/8.bmp + cp 9.bmp line_patterns.app/Contents/MacOS/9.bmp + $(CXX) $(CXXFLAGS) ../line_patterns.o $(PLATFORMSOURCES) -o line_patterns.app/Contents/MacOS/line_patterns $(LIBS) + +lion: ../lion.o ../parse_lion.o $(PLATFORMSOURCES) lion.app + $(CXX) $(CXXFLAGS) ../lion.o ../parse_lion.o $(PLATFORMSOURCES) -o lion.app/Contents/MacOS/lion $(LIBS) + +lion_lens: ../lion_lens.o ../parse_lion.o $(PLATFORMSOURCES) lion_lens.app + $(CXX) $(CXXFLAGS) ../lion_lens.o ../parse_lion.o $(PLATFORMSOURCES) -o lion_lens.app/Contents/MacOS/lion_lens $(LIBS) + +lion_outline: ../lion_outline.o ../parse_lion.o $(PLATFORMSOURCES) lion_outline.app + $(CXX) $(CXXFLAGS) ../lion_outline.o ../parse_lion.o $(PLATFORMSOURCES) -o lion_outline.app/Contents/MacOS/lion_outline $(LIBS) + +mol_view: ../mol_view.o $(PLATFORMSOURCES) 1.sdf mol_view.app + cp 1.sdf mol_view.app/Contents/MacOS/1.sdf + $(CXX) $(CXXFLAGS) ../mol_view.o $(PLATFORMSOURCES) -o mol_view.app/Contents/MacOS/mol_view $(LIBS) + +multi_clip: ../multi_clip.o ../parse_lion.o $(PLATFORMSOURCES) multi_clip.app + $(CXX) $(CXXFLAGS) ../multi_clip.o ../parse_lion.o $(PLATFORMSOURCES) -o multi_clip.app/Contents/MacOS/multi_clip $(LIBS) + +pattern_fill: ../pattern_fill.o $(PLATFORMSOURCES) pattern_fill.app + $(CXX) $(CXXFLAGS) ../pattern_fill.o $(PLATFORMSOURCES) -o pattern_fill.app/Contents/MacOS/pattern_fill $(LIBS) + +pattern_perspective: ../pattern_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) agg.bmp pattern_perspective.app + cp agg.bmp pattern_perspective.app/Contents/MacOS/agg.bmp + $(CXX) $(CXXFLAGS) ../pattern_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) -o pattern_perspective.app/Contents/MacOS/pattern_perspective $(LIBS) + +perspective: ../perspective.o ../interactive_polygon.o ../parse_lion.o $(PLATFORMSOURCES) perspective.app + $(CXX) $(CXXFLAGS) ../perspective.o ../interactive_polygon.o ../parse_lion.o $(PLATFORMSOURCES) -o perspective.app/Contents/MacOS/perspective $(LIBS) + +polymorphic_renderer: ../polymorphic_renderer.o $(PLATFORMSOURCES) polymorphic_renderer.app + $(CXX) $(CXXFLAGS) ../polymorphic_renderer.o $(PLATFORMSOURCES) -o polymorphic_renderer.app/Contents/MacOS/polymorphic_renderer $(LIBS) + +raster_text: ../raster_text.o $(PLATFORMSOURCES) raster_text.app + $(CXX) $(CXXFLAGS) ../raster_text.o $(PLATFORMSOURCES) -o raster_text.app/Contents/MacOS/raster_text $(LIBS) + +rasterizers: ../rasterizers.o $(PLATFORMSOURCES) rasterizers.app + $(CXX) $(CXXFLAGS) ../rasterizers.o $(PLATFORMSOURCES) -o rasterizers.app/Contents/MacOS/rasterizers $(LIBS) + +rasterizers2: ../rasterizers2.o $(PLATFORMSOURCES) rasterizers2.app + $(CXX) $(CXXFLAGS) ../rasterizers2.o $(PLATFORMSOURCES) -o rasterizers2.app/Contents/MacOS/rasterizers2 $(LIBS) + +rasterizer_compound: ../rasterizer_compound.o $(PLATFORMSOURCES) rasterizer_compound.app + $(CXX) $(CXXFLAGS) ../rasterizer_compound.o $(PLATFORMSOURCES) -o rasterizer_compound.app/Contents/MacOS/rasterizer_compound $(LIBS) + +rounded_rect: ../rounded_rect.o $(PLATFORMSOURCES) rounded_rect.app + $(CXX) $(CXXFLAGS) ../rounded_rect.o $(PLATFORMSOURCES) -o rounded_rect.app/Contents/MacOS/rounded_rect $(LIBS) + +scanline_boolean: ../scanline_boolean.o ../interactive_polygon.o $(PLATFORMSOURCES) scanline_boolean.app + $(CXX) $(CXXFLAGS) ../scanline_boolean.o ../interactive_polygon.o $(PLATFORMSOURCES) -o scanline_boolean.app/Contents/MacOS/scanline_boolean $(LIBS) + +scanline_boolean2: ../scanline_boolean2.o ../make_arrows.o ../make_gb_poly.o $(PLATFORMSOURCES) scanline_boolean2.app + $(CXX) $(CXXFLAGS) ../scanline_boolean2.o ../make_arrows.o ../make_gb_poly.o $(PLATFORMSOURCES) -o scanline_boolean2.app/Contents/MacOS/scanline_boolean2 $(LIBS) + +simple_blur: ../simple_blur.o ../parse_lion.o $(PLATFORMSOURCES) simple_blur.app + $(CXX) $(CXXFLAGS) ../simple_blur.o ../parse_lion.o $(PLATFORMSOURCES) -o simple_blur.app/Contents/MacOS/simple_blur $(LIBS) + +trans_polar: ../trans_polar.o $(PLATFORMSOURCES) trans_polar.app + $(CXX) $(CXXFLAGS) ../trans_polar.o $(PLATFORMSOURCES) -o trans_polar.app/Contents/MacOS/trans_polar $(LIBS) + + +clean: + rm -rf *.app + rm -f ../*.o + rm -f ../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f ../../src/platform/$(PLATFORM)/agg_mac_pmap.o + +agg.bmp: + cp ../art/agg.bmp . + +compositing.bmp: + cp ../art/compositing.bmp . + +spheres.bmp: + cp ../art/spheres.bmp . + +1.sdf: + cp ../art/1.sdf . + +1.bmp: + cp ../art/line_patterns.bmp.zip . + unzip -o line_patterns.bmp.zip + +%.app: + mkdir $*.app + mkdir $*.app/Contents + mkdir $*.app/Contents/MacOS + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + +.PHONY : clean + + diff --git a/examples/macosx_carbon/readme.txt b/examples/macosx_carbon/readme.txt new file mode 100644 index 0000000..7aad9ab --- /dev/null +++ b/examples/macosx_carbon/readme.txt @@ -0,0 +1,24 @@ +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/macosx_carbon +make clean +make + +Alternatively you can also build the examples one by one, using the example name directly: + +make aa_demo +make aa_test +... \ No newline at end of file diff --git a/examples/macosx_sdl/Makefile b/examples/macosx_sdl/Makefile new file mode 100644 index 0000000..5f8c791 --- /dev/null +++ b/examples/macosx_sdl/Makefile @@ -0,0 +1,358 @@ +include ../../Makefile.in.$(shell uname).SDL + +PLATFORM=sdl + +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 \ +-L../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm + +base: + cd ../../src/; make + make aa_demo + make aa_test + make alpha_gradient + make alpha_mask + make alpha_mask2 + make alpha_mask3 + make bspline + make blur + make blend_color + make bezier_div + make circles + make component_rendering + make conv_contour + make conv_dash_marker + make conv_stroke + make gamma_correction + make gamma_ctrl + make gouraud + 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 line_patterns + 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.bmp + $(CXX) $(CXXFLAGS) ../compositing.o $(PLATFORMSOURCES) -o compositing $(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.bmp + $(CXX) $(CXXFLAGS) ../distortions.o $(PLATFORMSOURCES) -o distortions $(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) + +gouraud: ../gouraud.o $(PLATFORMSOURCES) + $(CXX) $(CXXFLAGS) $^ -o gouraud $(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.bmp + $(CXX) $(CXXFLAGS) ../image_alpha.o $(PLATFORMSOURCES) -o image_alpha $(LIBS) + +image_filters: ../image_filters.o $(PLATFORMSOURCES) spheres.bmp + $(CXX) $(CXXFLAGS) ../image_filters.o $(PLATFORMSOURCES) -o image_filters $(LIBS) + +image_filters2: ../image_filters2.o $(PLATFORMSOURCES) spheres.bmp + $(CXX) $(CXXFLAGS) ../image_filters2.o $(PLATFORMSOURCES) -o image_filters2 $(LIBS) + +image_fltr_graph: ../image_fltr_graph.o $(PLATFORMSOURCES) spheres.bmp + $(CXX) $(CXXFLAGS) ../image_fltr_graph.o $(PLATFORMSOURCES) -o image_fltr_graph $(LIBS) + +image_perspective: ../image_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) spheres.bmp + $(CXX) $(CXXFLAGS) ../image_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) -o image_perspective $(LIBS) + +image_resample: ../image_resample.o ../interactive_polygon.o $(PLATFORMSOURCES) spheres.bmp + $(CXX) $(CXXFLAGS) ../image_resample.o ../interactive_polygon.o $(PLATFORMSOURCES) -o image_resample $(LIBS) + +image_transforms: ../image_transforms.o $(PLATFORMSOURCES) spheres.bmp + $(CXX) $(CXXFLAGS) ../image_transforms.o $(PLATFORMSOURCES) -o image_transforms $(LIBS) + +image1: ../image1.o $(PLATFORMSOURCES) spheres.bmp + $(CXX) $(CXXFLAGS) ../image1.o $(PLATFORMSOURCES) -o image1 $(LIBS) + +line_patterns: ../line_patterns.o $(PLATFORMSOURCES) 1.bmp 2.bmp 3.bmp 4.bmp 5.bmp 6.bmp 7.bmp 8.bmp 9.bmp + $(CXX) $(CXXFLAGS) ../line_patterns.o $(PLATFORMSOURCES) -o line_patterns $(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.bmp + $(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 -f aa_demo + rm -f aa_test + rm -f alpha_gradient + rm -f alpha_mask + rm -f alpha_mask2 + rm -f alpha_mask3 + rm -f blur + rm -f blend_color + rm -f bezier_div + rm -f bspline + rm -f circles + rm -f component_rendering + rm -f conv_contour + rm -f conv_dash_marker + rm -f conv_stroke + rm -f gamma_correction + rm -f gamma_ctrl + rm -f gouraud + rm -f gradients + rm -f gradient_focal + rm -f graph_test + rm -f idea + rm -f lion + rm -f lion_lens + rm -f lion_outline + rm -f multi_clip + rm -f pattern_fill + rm -f perspective + rm -f polymorphic_renderer + rm -f raster_text + rm -f rasterizers + rm -f rasterizers2 + rm -f rounded_rect + rm -f scanline_boolean + rm -f scanline_boolean2 + rm -f simple_blur + rm -f trans_polar + rm -f image_alpha + rm -f image_filters + rm -f image_filters2 + rm -f image_fltr_graph + rm -f image_perspective + rm -f image_resample + rm -f image_transforms + rm -f image1 + rm -f distortions + rm -f pattern_perspective + rm -f compositing + rm -f line_patterns + rm -f mol_view + rm -f freetype_test + rm -f trans_curve1_ft + rm -f trans_curve2_ft + rm -f gpc_test + +agg.bmp: + cp ../art/agg.bmp . + +compositing.bmp: + cp ../art/compositing.bmp . + +spheres.bmp: + cp ../art/spheres.bmp . + +1.sdf: + cp ../art/1.sdf . + +1.bmp: + cp ../art/line_patterns.bmp.zip . + unzip -o line_patterns.bmp.zip + +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 + + diff --git a/examples/macosx_sdl/readme.txt b/examples/macosx_sdl/readme.txt new file mode 100644 index 0000000..015b506 --- /dev/null +++ b/examples/macosx_sdl/readme.txt @@ -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/sdl +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 +... \ No newline at end of file diff --git a/examples/make_arrows.cpp b/examples/make_arrows.cpp new file mode 100644 index 0000000..77b2879 --- /dev/null +++ b/examples/make_arrows.cpp @@ -0,0 +1,43 @@ +#include "agg_path_storage.h" + +void make_arrows(agg::path_storage& ps) +{ + ps.remove_all(); + + ps.move_to(1330.599999999999909,1282.399999999999864); + ps.line_to(1377.400000000000091,1282.399999999999864); + ps.line_to(1361.799999999999955,1298.000000000000000); + ps.line_to(1393.000000000000000,1313.599999999999909); + ps.line_to(1361.799999999999955,1344.799999999999955); + ps.line_to(1346.200000000000045,1313.599999999999909); + ps.line_to(1330.599999999999909,1329.200000000000045); + ps.close_polygon(); + + ps.move_to(1330.599999999999909,1266.799999999999955); + ps.line_to(1377.400000000000091,1266.799999999999955); + ps.line_to(1361.799999999999955,1251.200000000000045); + ps.line_to(1393.000000000000000,1235.599999999999909); + ps.line_to(1361.799999999999955,1204.399999999999864); + ps.line_to(1346.200000000000045,1235.599999999999909); + ps.line_to(1330.599999999999909,1220.000000000000000); + ps.close_polygon(); + + ps.move_to(1315.000000000000000,1282.399999999999864); + ps.line_to(1315.000000000000000,1329.200000000000045); + ps.line_to(1299.400000000000091,1313.599999999999909); + ps.line_to(1283.799999999999955,1344.799999999999955); + ps.line_to(1252.599999999999909,1313.599999999999909); + ps.line_to(1283.799999999999955,1298.000000000000000); + ps.line_to(1268.200000000000045,1282.399999999999864); + ps.close_polygon(); + + ps.move_to(1268.200000000000045,1266.799999999999955); + ps.line_to(1315.000000000000000,1266.799999999999955); + ps.line_to(1315.000000000000000,1220.000000000000000); + ps.line_to(1299.400000000000091,1235.599999999999909); + ps.line_to(1283.799999999999955,1204.399999999999864); + ps.line_to(1252.599999999999909,1235.599999999999909); + ps.line_to(1283.799999999999955,1251.200000000000045); + ps.close_polygon(); + +} diff --git a/examples/make_gb_poly.cpp b/examples/make_gb_poly.cpp new file mode 100644 index 0000000..15f76a9 --- /dev/null +++ b/examples/make_gb_poly.cpp @@ -0,0 +1,1894 @@ +#include "agg_path_storage.h" + +static double poly1[] = +{ + 1250.8,1312.4, + 1252.8,1311.6, + 1254,1312, + 1254.8,1313.6, + 1254.8,1314.8, + 1256,1314, + 1257.6,1313.6, + 1258.4,1314.4, + 1260.4,1315.6, + 1261.6,1315.6, + 1262.4,1315.6, + 1263.2,1315.6, + 1264.8,1314.8, + 1266,1315.2, + 1266.8,1315.2, + 1267.2,1312.8, + 1266.8,1311.2, + 1267.6,1310.8, + 1268,1310.4, + 1268,1308.8, + 1268.8,1308.4, + 1270,1307.2, + 1270,1306.8, + 1270,1305.6, + 1270.8,1305.6, + 1271.2,1304, + 1271.2,1304, + 1270.4,1305.6, + 1270.8,1306.4, + 1271.2,1306, + 1271.6,1305.6, + 1272,1304.8, + 1271.6,1303.2, + 1271.2,1302.8, + 1269.2,1302, + 1268.4,1300.4, + 1268.4,1300, + 1269.2,1300.4, + 1270.8,1302.4, + 1272.4,1302, + 1273.2,1302, + 1273.6,1300.4, + 1274.8,1299.2, + 1274.4,1298, + 1275.2,1297.2, + 1274.4,1295.6, + 1274.4,1294.8, + 1274.4,1294.4, + 1274.4,1293.6, + 1273.6,1293.6, + 1273.6,1293.6, + 1273.2,1295.2, + 1273.6,1296.4, + 1273.6,1297.6, + 1273.2,1298, + 1272,1299.2, + 1271.6,1299.2, + 1271.2,1298, + 1272,1298, + 1271.6,1297.6, + 1272,1297.2, + 1272.4,1295.6, + 1270.8,1294, + 1272.8,1294.8, + 1273.2,1293.6, + 1273.6,1293.2, + 1272.8,1292.4, + 1271.6,1291.2, + 1271.2,1291.6, + 1270.4,1292, + 1268.8,1290.8, + 1268.8,1289.2, + 1268.4,1287.6, + 1266,1286.4, + 1265.2,1286.4, + 1265.6,1287.2, + 1264.4,1287.6, + 1264,1287.6, + 1263.2,1288, + 1264,1287.6, + 1264.4,1286.4, + 1264.8,1286.4, + 1265.2,1286, + 1264,1285.2, + 1262,1286.4, + 1261.6,1286.4, + 1261.6,1286.4, + 1261.6,1285.6, + 1261.2,1284, + 1261.6,1283.2, + 1262.8,1283.2, + 1262.8,1281.6, + 1263.2,1280.8, + 1263.2,1280, + 1263.2,1278.4, + 1263.2,1277.6, + 1265.2,1275.6, + 1264.8,1274.4, + 1264,1272.4, + 1264.4,1271.2, + 1265.2,1271.2, + 1265.6,1270.4, + 1264,1271.2, + 1263.6,1270.4, + 1263.2,1270.4, + 1263.6,1269.2, + 1264.4,1268.4, + 1264.4,1266.8, + 1265.2,1264.4, + 1264.8,1261.6, + 1266,1261.2, + 1264.8,1258.4, + 1264,1257.6, + 1263.2,1256, + 1262,1254, + 1262.4,1251.6, + 1260,1247.6, + 1259.6,1246.8, + 1258.8,1247.2, + 1258.8,1246.8, + 1258.8,1246, + 1259.2,1245.6, + 1259.2,1246, + 1259.2,1244.4, + 1260,1243.6, + 1259.2,1242.4, + 1258.8,1242.4, + 1259.2,1242.8, + 1258,1242.4, + 1258,1242.8, + 1257.6,1242.8, + 1256,1242.4, + 1254.4,1244, + 1253.2,1243.2, + 1253.6,1244, + 1253.2,1244, + 1252.8,1244, + 1252.4,1243.6, + 1252.8,1242.8, + 1252.4,1242.8, + 1251.6,1242, + 1250.8,1241.2, + 1250.8,1241.6, + 1251.6,1242, + 1251.6,1242.8, + 1251.2,1243.6, + 1250.8,1244, + 1250.4,1245.2, + 1250.8,1243.6, + 1250.4,1242.8, + 1250.8,1242.8, + 1250,1241.6, + 1248.4,1242, + 1249.2,1243.2, + 1248.4,1243.2, + 1248.4,1243.2, + 1248.4,1242.4, + 1247.6,1242.4, + 1247.2,1242, + 1243.6,1242, + 1242,1241.6, + 1242,1241.2, + 1241.2,1241.6, + 1240.8,1241.2, + 1241.2,1240.4, + 1242,1240, + 1241.6,1240, + 1241.6,1239.2, + 1239.6,1239.2, + 1239.2,1238, + 1238.4,1238, + 1237.6,1238, + 1237.2,1238.8, + 1236.8,1238, + 1236.4,1238, + 1236.8,1236.8, + 1235.2,1236.4, + 1234.4,1235.6, + 1234.8,1235.2, + 1232.4,1234.8, + 1231.2,1235.2, + 1231.2,1235.6, + 1232.4,1236, + 1232.8,1236.8, + 1230.8,1236.4, + 1229.6,1237.2, + 1229.2,1236.4, + 1230,1236.4, + 1230.8,1235.6, + 1230.4,1234.8, + 1230.4,1234.4, + 1229.6,1233.2, + 1228.4,1233.2, + 1228,1232.8, + 1226.8,1233.2, + 1227.2,1232.8, + 1226.4,1232, + 1226.4,1230.8, + 1226,1231.2, + 1224.4,1231.2, + 1224,1229.6, + 1223.2,1229.6, + 1223.2,1230.4, + 1221.6,1230.8, + 1221.2,1229.2, + 1220.4,1229.2, + 1220.4,1229.2, + 1219.6,1230.4, + 1218.4,1229.6, + 1217.6,1230.8, + 1218,1229.6, + 1216.8,1229.6, + 1216.8,1230, + 1216.8,1228.8, + 1216.4,1228.8, + 1216,1228.8, + 1216.4,1228.8, + 1215.6,1229.2, + 1215.6,1228.8, + 1214.8,1228.8, + 1214.4,1228.8, + 1214,1229.2, + 1214.4,1230.4, + 1213.6,1231.6, + 1213.6,1230.8, + 1212.8,1230.4, + 1212,1230.8, + 1212,1229.6, + 1211.6,1229.6, + 1211.2,1229.2, + 1210.8,1229.6, + 1210.8,1230.8, + 1209.6,1229.6, + 1210,1229.6, + 1208.8,1229.2, + 1208.8,1230, + 1208,1229.2, + 1208,1230, + 1208,1230, + 1209.6,1231.2, + 1210.8,1231.2, + 1212.4,1232.8, + 1212,1232.8, + 1208.4,1231.2, + 1208,1231.2, + 1208.8,1232, + 1209.6,1232.8, + 1214,1234, + 1214,1234, + 1214,1234.4, + 1213.6,1234.8, + 1213.2,1235.6, + 1212.8,1236, + 1212.8,1235.6, + 1212,1234, + 1207.2,1233.6, + 1206.8,1233.2, + 1205.2,1233.2, + 1204.8,1233.2, + 1204,1233.2, + 1203.6,1233.2, + 1203.6,1233.2, + 1203.6,1233.6, + 1204.8,1233.2, + 1204.8,1234, + 1204.4,1234.4, + 1204.8,1234.4, + 1206.4,1234.8, + 1206.8,1235.6, + 1206,1235.6, + 1206.4,1236.4, + 1207.6,1236.8, + 1208,1236.4, + 1208,1236.8, + 1209.6,1236.8, + 1208.8,1237.2, + 1210,1238.4, + 1211.2,1238.8, + 1212.4,1238.4, + 1210.4,1238.8, + 1209.2,1238, + 1208.4,1238, + 1208,1237.6, + 1207.6,1238, + 1204,1236.4, + 1204,1236.8, + 1202.8,1237.2, + 1203.2,1237.6, + 1203.6,1238.4, + 1203.2,1239.2, + 1202.4,1238.8, + 1201.2,1238, + 1201.6,1239.6, + 1200.8,1239.6, + 1200.4,1240.4, + 1202.4,1240.8, + 1202.8,1240.4, + 1202.4,1241.2, + 1202,1241.6, + 1202.8,1242, + 1202.8,1242.4, + 1206.8,1243.6, + 1207.6,1244.8, + 1207.6,1244, + 1208,1243.6, + 1208.8,1245.6, + 1209.2,1245.2, + 1210.4,1245.2, + 1208.8,1246, + 1207.6,1246, + 1207.6,1245.2, + 1207.2,1246, + 1204.4,1245.2, + 1203.6,1246, + 1202.8,1246, + 1202.4,1246, + 1203.2,1245.6, + 1202.8,1245.2, + 1201.2,1246, + 1202,1245.6, + 1200.8,1245.6, + 1200,1246, + 1200,1246.4, + 1200,1246.8, + 1200.4,1247.2, + 1200,1247.6, + 1200.8,1247.6, + 1200.8,1247.2, + 1201.6,1247.2, + 1201.6,1248.8, + 1202.4,1248.4, + 1203.2,1249.2, + 1204.8,1249.6, + 1204.8,1248.4, + 1206,1248, + 1206.8,1249.6, + 1206.4,1250, + 1207.2,1250.4, + 1206.8,1249.2, + 1208,1248, + 1209.2,1248, + 1209.6,1248, + 1209.6,1248, + 1210.8,1248, + 1210.8,1248.4, + 1208.8,1248.8, + 1208.8,1250, + 1209.6,1249.6, + 1209.6,1250, + 1210,1251.2, + 1208.4,1252, + 1208.4,1252.4, + 1211.2,1252.8, + 1212.4,1254, + 1213.2,1253.2, + 1212.8,1254, + 1212.4,1254, + 1212.4,1254, + 1212.8,1255.2, + 1213.6,1255.6, + 1215.6,1254.8, + 1215.6,1255.2, + 1217.6,1254.8, + 1221.2,1256, + 1221.2,1255.2, + 1222,1255.2, + 1222.8,1256.4, + 1224.4,1256, + 1224.8,1256.4, + 1226,1256.4, + 1224,1257.2, + 1222.8,1257.2, + 1222.8,1257.6, + 1222.4,1258.8, + 1221.2,1258.4, + 1221.2,1257.6, + 1219.6,1255.6, + 1218.4,1256, + 1217.6,1254.8, + 1217.2,1255.6, + 1218,1256.4, + 1216,1256, + 1214.8,1256.4, + 1214.4,1257.2, + 1214,1257.6, + 1214.4,1256.4, + 1212.4,1256.4, + 1212.4,1255.6, + 1209.6,1256, + 1208.8,1256, + 1210.4,1256.4, + 1212.8,1258.4, + 1214,1259.6, + 1215.2,1259.6, + 1215.2,1260.8, + 1216,1261.2, + 1216,1262.8, + 1217.6,1263.6, + 1217.2,1263.6, + 1215.6,1264, + 1215.6,1264, + 1216.4,1264.4, + 1218.8,1268, + 1220.4,1267.6, + 1221.6,1268, + 1221.2,1268, + 1222.8,1268, + 1221.6,1268, + 1223.2,1268, + 1223.2,1268, + 1223.6,1267.6, + 1223.6,1267.6, + 1223.6,1268.4, + 1224.4,1269.6, + 1223.6,1269.2, + 1222.8,1269.6, + 1223.2,1270, + 1223.6,1270.4, + 1224,1270.4, + 1224,1271.2, + 1222.4,1271.2, + 1220.4,1270.4, + 1216,1270.4, + 1215.2,1270.8, + 1215.2,1272.4, + 1215.2,1272, + 1214.8,1270.8, + 1214.8,1270.8, + 1214.8,1271.6, + 1214.8,1272.4, + 1214.8,1273.2, + 1214.8,1273.2, + 1215.2,1273.2, + 1214.8,1273.6, + 1214.8,1273.2, + 1214.8,1273.6, + 1214.4,1273.6, + 1214.8,1274, + 1214.4,1274, + 1213.6,1273.2, + 1213.2,1272.8, + 1212,1273.6, + 1211.2,1273.6, + 1211.6,1274.4, + 1211.2,1274.4, + 1213.2,1275.2, + 1213.2,1275.2, + 1212.8,1275.2, + 1212.8,1275.6, + 1211.6,1275.6, + 1211.6,1275.6, + 1211.6,1275.6, + 1211.2,1275.6, + 1210.8,1275.6, + 1210.4,1274.8, + 1209.2,1275.6, + 1208.8,1276, + 1208,1275.6, + 1207.6,1276.4, + 1207.2,1276, + 1208,1277.6, + 1209.2,1277.2, + 1208.4,1278, + 1208.4,1278.8, + 1208,1279.2, + 1207.2,1279.6, + 1208.8,1279.2, + 1208.8,1280, + 1210.4,1279.6, + 1209.6,1281.2, + 1212,1281.2, + 1212,1282.4, + 1212.4,1283.6, + 1214,1284.4, + 1215.6,1284, + 1216.4,1284.8, + 1215.6,1284.8, + 1216,1285.2, + 1215.6,1285.2, + 1216,1286.4, + 1216,1286.4, + 1216.4,1286.8, + 1214,1286.8, + 1213.2,1286.8, + 1212,1286.8, + 1212,1286.8, + 1212.4,1288.8, + 1213.6,1288, + 1214,1287.6, + 1214,1287.6, + 1214,1289.2, + 1213.6,1289.2, + 1213.6,1288.4, + 1213.6,1289.2, + 1213.6,1289.6, + 1212.8,1290.4, + 1212.8,1291.2, + 1213.6,1291.6, + 1213.2,1291.6, + 1214,1292.4, + 1213.2,1292.4, + 1213.2,1291.6, + 1212.4,1292, + 1212,1292, + 1212,1292, + 1212.8,1292.8, + 1212.4,1293.2, + 1212.8,1293.6, + 1212.4,1294, + 1212.8,1294.4, + 1212.8,1294.4, + 1211.6,1295.2, + 1211.6,1294.4, + 1211.2,1294.4, + 1211.6,1294, + 1210.8,1294, + 1210.8,1293.6, + 1210.4,1293.2, + 1210.8,1292, + 1210,1292.4, + 1210.4,1295.2, + 1210.8,1295.2, + 1210,1296, + 1210.8,1296, + 1210.8,1296.4, + 1212,1297.6, + 1212.4,1296.4, + 1213.2,1295.6, + 1212.8,1294.8, + 1212,1295.6, + 1212,1295.2, + 1213.6,1294.8, + 1213.6,1296, + 1214,1295.6, + 1214,1296.4, + 1214,1296.4, + 1213.6,1297.2, + 1214,1297.6, + 1215.6,1297.2, + 1218.4,1296.8, + 1219.6,1295.2, + 1220.4,1296.4, + 1221.2,1296, + 1221.6,1295.2, + 1222.4,1294.8, + 1222,1294.4, + 1222.4,1294, + 1222,1293.6, + 1222.8,1293.2, + 1223.2,1292.8, + 1224.4,1295.2, + 1226,1295.2, + 1227.6,1294, + 1228.4,1294.4, + 1228.8,1294.4, + 1229.6,1294, + 1230.8,1292.8, + 1231.6,1292.8, + 1230.8,1294, + 1230.4,1294, + 1231.2,1294.4, + 1232.4,1294.4, + 1231.2,1295.6, + 1231.2,1295.6, + 1232.4,1295.2, + 1232.4,1295.6, + 1231.6,1296, + 1230.4,1295.6, + 1230,1296, + 1231.2,1296.8, + 1231.2,1297.6, + 1231.6,1297.6, + 1232.8,1298, + 1232.4,1298.8, + 1232.8,1299.2, + 1233.2,1298.8, + 1235.2,1298.8, + 1236,1300, + 1236.4,1300.4, + 1237.6,1302.4, + 1238,1302.4, + 1238.4,1302, + 1238,1302.4, + 1236,1302.4, + 1235.6,1302.4, + 1235.6,1302.4, + 1235.6,1302.4, + 1234.8,1302.4, + 1233.2,1300.8, + 1233.2,1302, + 1234.4,1302.4, + 1234.4,1302.4, + 1233.2,1302.4, + 1232.8,1302.4, + 1231.6,1302.4, + 1230.4,1302.4, + 1228.8,1304, + 1229.2,1304.4, + 1228.8,1304.4, + 1229.6,1304.4, + 1229.2,1305.6, + 1230.4,1306.4, + 1234,1305.6, + 1233.2,1306.4, + 1232.4,1306.4, + 1233.2,1306.4, + 1234.4,1305.6, + 1232.4,1307.6, + 1233.2,1307.6, + 1235.6,1307.6, + 1234.8,1308.4, + 1234.8,1308.8, + 1235.6,1308.4, + 1236,1308.4, + 1235.6,1308.8, + 1234.8,1309.2, + 1234.8,1308.8, + 1234,1309.2, + 1234,1310.4, + 1235.2,1310.4, + 1234.8,1310.4, + 1234,1312, + 1234.8,1312, + 1234.8,1312.8, + 1235.6,1312.4, + 1235.6,1313.2, + 1236,1313.2, + 1236,1313.2, + 1236.4,1313.2, + 1236.4,1313.6, + 1236.8,1314.8, + 1238.4,1314.4, + 1238.8,1314.4, + 1238.8,1314.4, + 1238.4,1314, + 1239.6,1314.4, + 1240.4,1314.8, + 1240.4,1316.4, + 1240.8,1316.8, + 1241.6,1316.4, + 1241.6,1315.6, + 1242,1315.6, + 1242.4,1314.8, + 1242,1314.4, + 1242.8,1314.4, + 1242,1314.4, + 1242.8,1314.4, + 1242.8,1314.4, + 1243.2,1315.6, + 1242.4,1315.6, + 1242,1316.8, + 1242.8,1316.8, + 1243.2,1316.8, + 1243.2,1314.8, + 1244,1314.4, + 1244.8,1314, + 1244.8,1313.2, + 1245.2,1314, + 1244.8,1316.4, + 1244.4,1314.4, + 1244.4,1315.2, + 1244.4,1316, + 1243.6,1316.4, + 1244,1316.8, + 1244.4,1316.8, + 1245.2,1317.6, + 1246,1316.8, + 1246,1315.2, + 1246.8,1314, + 1246.8,1314, + 1246.8,1312.8, + 1245.2,1311.6, + 1246,1311.6, + 1246.4,1311.6, + 1245.2,1311.2, + 1244.8,1310, + 1246.4,1311.6, + 1247.6,1312, + 1247.6,1312.4, + 1247.6,1314, + 1246.8,1316, + 1247.6,1316.4, + 1246.8,1317.2, + 1247.6,1317.2, + 1247.6,1317.2, + 1248,1317.2, + 1249.2,1317.6, + 1249.6,1317.6, + 1249.6,1317.2, + 1250.8,1317.2, + 1249.6,1317.6, + 1249.2,1318.4, + 1249.6,1318.4, + 1249.2,1319.2, + 1248.8,1319.6, + 1248.8,1319.6, + 1250.8,1319.2, + 1251.6,1318.4, + 1252.4,1317.6, + 1255.2,1316, + 1255.2,1315.6, + 1252,1314 +}; + + +static double poly2[] = +{ + 1284,1396.4, + 1284.4,1395.6, + 1285.2,1395.6, + 1286,1395.2, + 1286,1394.8, + 1286.8,1395.2, + 1286.4,1395.2, + 1286.4,1395.2, + 1286.8,1394.8, + 1288,1394, + 1288,1393.6, + 1286.8,1391.6, + 1288,1392.8, + 1288,1393.6, + 1288.8,1393.6, + 1288.8,1394.8, + 1290,1394.4, + 1290.8,1393.6, + 1291.2,1393.2, + 1290.4,1391.2, + 1291.6,1393.6, + 1292.8,1393.6, + 1293.6,1392.8, + 1293.6,1393.2, + 1293.6,1394, + 1294.4,1393.6, + 1294.8,1394.4, + 1295.6,1394, + 1296,1394.8, + 1296,1394.4, + 1297.6,1394.4, + 1298.8,1394.4, + 1300.4,1394.8, + 1302,1394.8, + 1302,1394.4, + 1302.4,1394.4, + 1303.2,1395.2, + 1304.4,1394.8, + 1304.4,1395.2, + 1303.6,1396.4, + 1304.4,1396.8, + 1304.4,1396.4, + 1306.8,1396, + 1306.8,1395.6, + 1308.4,1396, + 1308.8,1395.6, + 1307.6,1392.8, + 1307.6,1392, + 1308.8,1392, + 1307.6,1389.6, + 1307.2,1389.2, + 1306.4,1387.6, + 1304.4,1387.2, + 1302.8,1384, + 1299.6,1382, + 1298.8,1381.6, + 1298,1380.8, + 1296.4,1379.2, + 1296,1377.6, + 1295.2,1377.6, + 1294.4,1377.2, + 1293.6,1376.8, + 1293.6,1376.4, + 1295.2,1376.4, + 1296.4,1376.8, + 1296.8,1376.8, + 1296.8,1376.4, + 1298,1376.4, + 1298.8,1377.6, + 1299.2,1377.2, + 1298,1375.2, + 1296.4,1373.6, + 1296,1373.6, + 1296,1374, + 1295.2,1374, + 1294,1373.2, + 1292.4,1373.6, + 1292.4,1372.4, + 1290.8,1371.2, + 1290.4,1370.4, + 1293.2,1372.8, + 1295.2,1372.8, + 1295.6,1373.6, + 1296.4,1372.8, + 1294.8,1371.2, + 1294.8,1371.2, + 1294.8,1370.4, + 1294,1370, + 1293.6,1369.6, + 1292.8,1370, + 1293.2,1369.6, + 1292.8,1368.8, + 1293.6,1368.4, + 1294,1368.4, + 1294,1368.4, + 1295.6,1370, + 1295.6,1370.4, + 1295.2,1371.2, + 1298,1371.2, + 1300.4,1372, + 1302,1372.4, + 1302.8,1373.6, + 1304.8,1374.4, + 1308.8,1372.4, + 1310.8,1373.6, + 1311.2,1373.2, + 1312.4,1373.2, + 1316.8,1372.4, + 1317.6,1372.4, + 1318.4,1373.2, + 1319.6,1372.4, + 1320.4,1373.2, + 1322,1373.2, + 1322,1372.4, + 1322.8,1372.8, + 1323.6,1372.4, + 1324,1371.6, + 1324,1370.4, + 1324.8,1368.8, + 1324.4,1368.8, + 1324.8,1368, + 1325.2,1368, + 1321.6,1363.2, + 1320.8,1360.4, + 1321.2,1359.6, + 1319.6,1356, + 1319.6,1354.4, + 1318.4,1352.4, + 1317.2,1351.2, + 1316.8,1351.2, + 1316.8,1349.2, + 1316.8,1349.2, + 1315.6,1348.4, + 1316,1347.6, + 1315.2,1346, + 1312.8,1344.4, + 1312.4,1344, + 1311.6,1344, + 1310.8,1343.6, + 1310,1344, + 1309.2,1343.6, + 1308.4,1343.6, + 1305.6,1342, + 1304.8,1341.6, + 1305.2,1341.2, + 1306.4,1342, + 1310.4,1343.6, + 1311.6,1343.2, + 1311.2,1342, + 1311.2,1341.6, + 1311.2,1341.6, + 1312,1340.4, + 1313.6,1340.4, + 1314.8,1338.8, + 1313.2,1338, + 1311.6,1337.6, + 1310,1337.6, + 1309.6,1337.6, + 1307.2,1335.2, + 1306.8,1334.4, + 1305.2,1334, + 1303.6,1332.8, + 1301.2,1334, + 1299.6,1334, + 1299.6,1332.8, + 1300,1332.8, + 1302,1332.8, + 1304,1332.4, + 1304.4,1332.8, + 1305.2,1332.4, + 1307.2,1332.4, + 1307.6,1331.6, + 1308.8,1331.6, + 1309.6,1332.4, + 1310,1332.4, + 1310.8,1332.8, + 1310.8,1333.6, + 1311.6,1334.4, + 1313.6,1334.4, + 1314.8,1332.8, + 1314.8,1332.8, + 1316,1332.8, + 1318.4,1330.8, + 1320.8,1330.4, + 1320.8,1330.4, + 1321.6,1329.6, + 1322.8,1326.8, + 1324.8,1324.4, + 1325.2,1324.4, + 1325.6,1324, + 1325.6,1323.6, + 1325.6,1323.2, + 1326.8,1323.2, + 1327.2,1323.2, + 1327.6,1321.6, + 1328.4,1320.4, + 1328.4,1319.2, + 1328,1318, + 1328.8,1316.8, + 1328.4,1315.6, + 1329.6,1313.2, + 1329.6,1312.4, + 1330.8,1309.2, + 1331.6,1308, + 1331.6,1307.2, + 1332.8,1303.6, + 1333.2,1302, + 1334.4,1301.6, + 1334,1301.6, + 1334.4,1300.8, + 1334.4,1299.6, + 1334.4,1299.6, + 1334.8,1299.6, + 1334.8,1300, + 1337.2,1299.2, + 1339.6,1298.4, + 1341.6,1297.2, + 1342.8,1296.8, + 1343.6,1296.4, + 1343.6,1295.6, + 1344.8,1294, + 1346,1292, + 1347.2,1291.2, + 1347.6,1289.6, + 1350,1288.8, + 1348.8,1287.6, + 1348,1286.4, + 1349.6,1282.8, + 1351.2,1280, + 1352.8,1277.2, + 1353.2,1275.6, + 1353.2,1275.6, + 1353.2,1276.4, + 1352.8,1276.8, + 1351.6,1277.2, + 1351.2,1276.8, + 1350.4,1276.8, + 1349.6,1277.2, + 1348,1279.2, + 1347.2,1279.6, + 1345.6,1278.4, + 1343.6,1278, + 1342.4,1278.8, + 1341.2,1278, + 1341.6,1277.6, + 1342.8,1278, + 1344,1277.6, + 1344.8,1277.6, + 1347.2,1278.4, + 1348,1278, + 1348.4,1277.2, + 1350.4,1275.6, + 1351.2,1275.6, + 1351.6,1274.4, + 1352.4,1273.2, + 1353.6,1273.2, + 1354,1272.4, + 1354.8,1271.2, + 1356,1267.6, + 1356.8,1266, + 1356.4,1264.4, + 1354,1262, + 1352.8,1259.6, + 1352.4,1259.6, + 1352,1259.2, + 1352.8,1259.2, + 1353.6,1259.2, + 1354,1258.8, + 1355.6,1257.2, + 1357.2,1257.6, + 1357.6,1256.4, + 1357.6,1256.8, + 1358,1258, + 1358.8,1260.8, + 1359.6,1261.6, + 1360.4,1261.2, + 1361.2,1261.6, + 1364,1261.2, + 1364.4,1261.6, + 1364.8,1261.6, + 1365.6,1261.6, + 1366.4,1261.6, + 1365.6,1262, + 1366,1262, + 1366.8,1262, + 1367.6,1261.6, + 1370.4,1261.2, + 1372.4,1259.6, + 1376,1257.2, + 1376.4,1257.2, + 1377.6,1254.4, + 1377.6,1252.8, + 1378,1251.6, + 1377.6,1250, + 1378,1248.8, + 1376.4,1245.6, + 1376.4,1243.6, + 1376,1241.2, + 1374,1240, + 1372.8,1237.2, + 1371.6,1238.8, + 1371.6,1237.6, + 1370,1238, + 1369.6,1237.6, + 1372,1237.6, + 1370.8,1235.2, + 1371.6,1235.2, + 1371.6,1236, + 1372,1235.2, + 1372,1235.2, + 1370.8,1234, + 1369.6,1233.2, + 1368.4,1233.6, + 1367.6,1234, + 1366.8,1234, + 1366,1233.2, + 1365.6,1232.4, + 1363.6,1232, + 1364.4,1231.6, + 1364.8,1231.6, + 1366.4,1232.8, + 1367.2,1232.4, + 1367.2,1231.2, + 1366.8,1229.6, + 1366.4,1229.6, + 1365.2,1229.2, + 1366,1229.6, + 1366.4,1229.2, + 1366.4,1229.6, + 1367.2,1229.6, + 1367.6,1229.2, + 1365.2,1227.2, + 1363.2,1227.2, + 1362,1226, + 1360.4,1226, + 1360,1226, + 1359.2,1225.2, + 1360,1225.2, + 1360.4,1226, + 1361.6,1226, + 1364,1226, + 1364.4,1225.2, + 1364,1224.8, + 1363.2,1224.8, + 1362.4,1224.4, + 1361.6,1224.4, + 1362.4,1223.6, + 1363.2,1223.6, + 1363.6,1223.6, + 1364,1223.6, + 1364,1224.4, + 1364.4,1224, + 1364.4,1224.4, + 1364.4,1225.2, + 1366.8,1224.8, + 1367.6,1223.2, + 1366.8,1223.2, + 1365.2,1222.8, + 1367.2,1222.8, + 1371.6,1224, + 1375.2,1224.4, + 1374.8,1223.2, + 1374,1222, + 1374.8,1220.4, + 1374.4,1218.4, + 1374,1218, + 1372,1217.2, + 1371.6,1217.2, + 1370.4,1216.4, + 1369.2,1215.6, + 1368.4,1214.4, + 1368.8,1212.8, + 1366,1212.8, + 1364.8,1212.4, + 1364,1211.6, + 1359.2,1210, + 1358.4,1208.4, + 1357.6,1207.6, + 1354.4,1208.8, + 1351.2,1210, + 1344,1208.4, + 1343.6,1207.6, + 1343.2,1208.4, + 1343.2,1207.2, + 1342.4,1207.2, + 1340.8,1208.4, + 1341.2,1208.4, + 1340.8,1209.6, + 1340.4,1209.2, + 1340,1209.6, + 1339.6,1209.6, + 1340,1209.2, + 1340.4,1208.4, + 1338.8,1208.4, + 1339.2,1208.4, + 1339.2,1209.6, + 1338.4,1209.2, + 1338.4,1208, + 1338,1208, + 1337.6,1208, + 1338,1209.2, + 1338,1210, + 1336.4,1209.2, + 1337.2,1208.8, + 1336.8,1208, + 1334.4,1209.2, + 1333.6,1210.4, + 1332,1211.2, + 1332,1210.8, + 1333.2,1210.4, + 1334.4,1208.8, + 1333.6,1208, + 1332.4,1208, + 1331.2,1206.8, + 1329.2,1206.8, + 1328,1206.8, + 1328.4,1206.8, + 1328.4,1206.8, + 1327.2,1206.8, + 1326.4,1206.8, + 1325.2,1205.6, + 1325.2,1206.8, + 1323.6,1206.8, + 1323.2,1205.6, + 1323.6,1206, + 1323.6,1205.2, + 1325.2,1205.2, + 1325.2,1204.4, + 1325.6,1204.4, + 1325.2,1204, + 1324.8,1203.2, + 1323.6,1203.2, + 1323.2,1203.2, + 1321.2,1204, + 1318,1204, + 1317.6,1203.6, + 1317.2,1202.8, + 1318,1202, + 1317.2,1201.2, + 1317.2,1202.4, + 1314.8,1204.4, + 1312.4,1206, + 1310.8,1206.4, + 1309.6,1205.6, + 1307.6,1205.6, + 1306,1205.6, + 1303.6,1203.2, + 1302.8,1203.6, + 1302,1205.2, + 1302.4,1203.2, + 1301.2,1201.2, + 1301.6,1200, + 1300.4,1199.2, + 1300.8,1198.8, + 1301.6,1198, + 1301.2,1198, + 1300.8,1197.6, + 1300,1197.2, + 1300,1196.8, + 1299.2,1196.4, + 1299.2,1195.6, + 1299.2,1194.4, + 1298,1194, + 1297.2,1194.4, + 1297.2,1194.4, + 1296.4,1194.4, + 1295.6,1196, + 1294.4,1196.8, + 1292.8,1196.8, + 1291.6,1196.8, + 1291.6,1197.6, + 1290.4,1198, + 1290.4,1198, + 1291.2,1197.6, + 1290.8,1196.8, + 1290,1196.8, + 1289.6,1198, + 1288.8,1198, + 1287.2,1198, + 1286.4,1197.2, + 1283.6,1197.2, + 1283.2,1197.2, + 1283.2,1197.6, + 1282,1197.2, + 1281.2,1194.8, + 1280,1195.2, + 1279.6,1194.4, + 1278.8,1194.4, + 1278.8,1192.8, + 1278,1192.8, + 1278.4,1192.8, + 1278,1192.8, + 1278,1195.2, + 1277.6,1195.2, + 1277.2,1194.4, + 1277.6,1193.6, + 1277.2,1192.8, + 1277.6,1192.8, + 1277.2,1192.8, + 1277.2,1192, + 1276.4,1192, + 1277.2,1191.6, + 1277.2,1190.8, + 1276.8,1190, + 1275.6,1190, + 1275.2,1188.8, + 1274.4,1190, + 1274,1191.2, + 1273.2,1191.6, + 1270.8,1193.2, + 1270,1192.8, + 1270,1192, + 1269.6,1191.2, + 1268,1190.8, + 1267.2,1191.6, + 1267.6,1192, + 1267.2,1193.6, + 1268,1193.2, + 1270,1195.2, + 1271.6,1194.4, + 1272.4,1195.2, + 1273.2,1195.2, + 1274,1196.4, + 1274.8,1197.6, + 1276,1198.4, + 1276,1199.2, + 1277.6,1199.6, + 1278.4,1200.8, + 1278,1201.6, + 1278.4,1202.4, + 1278.8,1202.4, + 1279.6,1203.2, + 1279.6,1202.8, + 1280,1203.6, + 1282,1203.6, + 1282,1205.2, + 1283.2,1206.4, + 1283.6,1207.2, + 1285.6,1208, + 1285.6,1210.8, + 1286.4,1213.2, + 1286.8,1213.2, + 1288.8,1212.8, + 1289.2,1212.8, + 1290.4,1213.6, + 1291.2,1214.4, + 1290,1216.4, + 1290.4,1216.4, + 1290.4,1216.8, + 1290.8,1216.8, + 1297.2,1218.8, + 1300,1218.4, + 1300.4,1218.4, + 1302.4,1217.6, + 1302.8,1217.2, + 1304.4,1217.2, + 1306,1217.6, + 1308,1217.6, + 1308.8,1218.4, + 1308.8,1218.8, + 1308.8,1220, + 1309.2,1220, + 1309.6,1222, + 1310.4,1222.8, + 1312.4,1224.4, + 1313.2,1224.8, + 1316.8,1230, + 1318,1230.8, + 1318,1231.6, + 1318,1230.8, + 1316.8,1230.8, + 1313.2,1227.2, + 1310.8,1226, + 1309.6,1225.6, + 1309.6,1225.6, + 1309.6,1225.6, + 1308.8,1225.6, + 1307.2,1224.4, + 1307.2,1223.6, + 1306.4,1223.6, + 1306.4,1222.8, + 1305.2,1222.4, + 1302.8,1222.4, + 1300.8,1222.8, + 1299.2,1224.4, + 1298.4,1224.4, + 1297.2,1225.6, + 1296.4,1228, + 1294,1228, + 1294,1227.6, + 1294,1226, + 1291.6,1226, + 1291.6,1226, + 1290.8,1225.6, + 1289.6,1226, + 1289.6,1227.2, + 1290,1227.6, + 1290.4,1227.6, + 1290.8,1227.6, + 1292.4,1228, + 1292.8,1228.8, + 1293.2,1229.2, + 1292,1228.8, + 1291.2,1229.6, + 1289.6,1229.2, + 1289.6,1229.2, + 1288.4,1230, + 1288.4,1230.8, + 1289.6,1230, + 1288.8,1231.2, + 1288.8,1232, + 1288.4,1231.2, + 1287.6,1231.6, + 1287.6,1230.8, + 1284.4,1230.4, + 1283.6,1229.2, + 1282.8,1229.2, + 1282.4,1228.4, + 1281.2,1228, + 1280,1227.6, + 1278.4,1228.4, + 1278.4,1229.2, + 1277.6,1229.2, + 1277.6,1229.6, + 1278.4,1229.2, + 1278.8,1229.6, + 1278.8,1229.6, + 1279.6,1229.6, + 1281.2,1230, + 1279.6,1230.4, + 1276.8,1230.4, + 1276.8,1229.6, + 1276,1230.4, + 1275.6,1231.2, + 1276.4,1231.2, + 1276.8,1232, + 1278,1232, + 1277.6,1234, + 1276.4,1234, + 1274.4,1234.4, + 1274.8,1236, + 1276,1235.6, + 1276.4,1236, + 1278,1236.8, + 1278,1237.6, + 1279.6,1237.2, + 1280,1237.2, + 1280.8,1237.2, + 1280.8,1238, + 1281.2,1237.2, + 1282,1237.6, + 1282,1238.4, + 1282.8,1238.8, + 1283.6,1240, + 1284,1240, + 1284,1240.8, + 1286.8,1240.4, + 1288.8,1242.4, + 1289.6,1242.4, + 1290.8,1242.8, + 1292,1244.8, + 1292.8,1246.4, + 1293.6,1249.6, + 1294.4,1250, + 1295.2,1250.4, + 1293.6,1250.4, + 1292.4,1251.6, + 1293.6,1254, + 1294.4,1255.2, + 1293.6,1254.4, + 1293.2,1255.2, + 1292.4,1255.6, + 1292,1256.4, + 1292.8,1257.6, + 1292,1258.4, + 1288.8,1258.4, + 1288,1257.6, + 1287.6,1256.8, + 1287.6,1256.4, + 1286.8,1255.2, + 1285.6,1256.8, + 1285.2,1256.4, + 1284,1256.8, + 1283.6,1256, + 1283.6,1256.8, + 1284,1257.6, + 1285.6,1258.8, + 1286.8,1259.6, + 1289.2,1261.6, + 1289.2,1263.6, + 1290,1263.6, + 1290,1263.6, + 1292,1266.4, + 1292.8,1266.8, + 1293.6,1266.8, + 1296.4,1267.6, + 1296.8,1267.6, + 1296.4,1268.8, + 1297.6,1268.4, + 1298.4,1267.6, + 1300,1268, + 1303.6,1269.2, + 1304.8,1269.2, + 1304.8,1268.8, + 1307.6,1266.4, + 1308,1267.6, + 1306,1270, + 1306.4,1270, + 1308.4,1271.2, + 1308.8,1270.4, + 1310,1268.4, + 1311.2,1268, + 1312.4,1268, + 1312.8,1268.8, + 1312,1268.8, + 1310.4,1268.8, + 1309.6,1270.4, + 1307.6,1273.2, + 1309.2,1277.2, + 1311.2,1278.8, + 1308.4,1278.8, + 1308,1280.4, + 1308.4,1282.8, + 1310.4,1283.6, + 1310.8,1283.2, + 1311.2,1284.4, + 1310.8,1284.4, + 1310.8,1284.8, + 1310.4,1284.8, + 1310,1285.6, + 1310.8,1286.8, + 1311.6,1286.8, + 1311.6,1287.6, + 1311.2,1289.2, + 1311.6,1290, + 1310.8,1290, + 1310,1288.4, + 1309.6,1288.4, + 1308.4,1290, + 1307.6,1287.6, + 1306.8,1286.4, + 1307.2,1286.4, + 1305.6,1287.6, + 1305.6,1288.4, + 1305.6,1288.8, + 1306,1288.8, + 1306.4,1291.2, + 1305.6,1289.6, + 1304.4,1289.6, + 1303.2,1291.6, + 1303.2,1292.8, + 1300,1297.2, + 1300.8,1299.2, + 1301.2,1300.4, + 1302,1302, + 1302.8,1303.2, + 1302.8,1304, + 1303.6,1305.6, + 1304.4,1306, + 1304.4,1305.6, + 1305.2,1305.6, + 1305.6,1306, + 1305.2,1306, + 1305.2,1306.8, + 1306,1307.6, + 1307.6,1306.8, + 1308.4,1307.2, + 1308.4,1307.6, + 1308,1307.6, + 1308,1308, + 1308.8,1308, + 1308.8,1308.4, + 1307.2,1308.4, + 1305.6,1308, + 1303.2,1308, + 1302.8,1308, + 1302,1308, + 1301.6,1308, + 1301.2,1308, + 1301.2,1308, + 1301.2,1305.6, + 1300.8,1305.6, + 1299.2,1306, + 1298.4,1305.6, + 1298,1306, + 1297.6,1305.6, + 1297.6,1306, + 1298,1306, + 1297.2,1305.2, + 1297.6,1304.8, + 1295.6,1303.2, + 1294.4,1303.2, + 1294.4,1304.8, + 1294,1303.6, + 1293.2,1303.6, + 1292,1304.8, + 1292.4,1306, + 1291.6,1304.8, + 1290.4,1306, + 1290,1306.4, + 1289.6,1307.2, + 1289.6,1306, + 1289.2,1306.4, + 1289.2,1304.8, + 1290.4,1304.4, + 1290,1303.6, + 1290.4,1301.6, + 1290,1301.6, + 1288,1301.6, + 1286.8,1303.6, + 1284.4,1304.8, + 1284,1306, + 1283.6,1306.4, + 1282.4,1305.2, + 1281.6,1304.4, + 1282.4,1301.6, + 1282.8,1301.6, + 1283.2,1301.2, + 1283.6,1300.4, + 1283.2,1300.4, + 1282,1301.2, + 1282,1302.4, + 1279.6,1306, + 1278.8,1308, + 1279.2,1309.6, + 1280,1309.6, + 1280.4,1309.6, + 1280.8,1307.6, + 1281.6,1306.4, + 1281.6,1307.2, + 1280.8,1309.6, + 1280.8,1310, + 1281.2,1312.4, + 1283.6,1314.8, + 1284,1317.2, + 1284.8,1317.6, + 1285.2,1319.2, + 1286.8,1319.6, + 1286.8,1320.4, + 1286.4,1321.6, + 1286,1321.6, + 1286.4,1322, + 1286,1323.2, + 1284.4,1324, + 1284.4,1324.4, + 1283.2,1326, + 1284,1326.8, + 1283.6,1328.4, + 1283.2,1330.8, + 1283.6,1331.2, + 1284.8,1332.4, + 1285.6,1330.8, + 1288.8,1330.8, + 1286.8,1332, + 1285.2,1333.2, + 1284.4,1334.4, + 1284.8,1333.2, + 1285.2,1332.8, + 1284.8,1332.8, + 1284,1332.8, + 1283.6,1334.4, + 1284.8,1335.6, + 1284,1335.2, + 1284,1336, + 1283.6,1336.4, + 1283.2,1335.6, + 1284,1334.8, + 1283.6,1333.2, + 1282.8,1333.2, + 1283.2,1332.8, + 1282,1330, + 1281.2,1330, + 1281.2,1331.2, + 1280.8,1332.8, + 1280.8,1330.8, + 1279.6,1331.2, + 1279.6,1332.8, + 1279.6,1332.8, + 1279.2,1330.8, + 1278.8,1330.8, + 1279.2,1329.2, + 1277.6,1330, + 1277.2,1330.8, + 1277.6,1333.2, + 1278.4,1334.8, + 1279.6,1335.6, + 1279.6,1336, + 1281.2,1336.8, + 1281.6,1338, + 1283.2,1339.6, + 1282,1338.8, + 1281.2,1338.8, + 1280.8,1337.2, + 1278.8,1336, + 1277.2,1333.2, + 1276.4,1333.2, + 1276,1333.2, + 1276,1332, + 1276.4,1331.2, + 1276.4,1330, + 1278,1328.4, + 1277.6,1327.6, + 1276.8,1327.2, + 1276,1326, + 1275.6,1324.8, + 1275.2,1323.6, + 1275.6,1323.2, + 1275.2,1322.8, + 1275.2,1322, + 1274,1319.6, + 1273.6,1319.6, + 1274,1319.6, + 1274.8,1318.4, + 1274,1317.2, + 1272,1316.4, + 1270.8,1316.8, + 1270.8,1319.2, + 1272,1319.6, + 1272.4,1322, + 1272,1323.2, + 1272.8,1324.4, + 1272.8,1325.2, + 1275.6,1329.2, + 1274,1328, + 1272.8,1328.4, + 1272.8,1329.6, + 1274.4,1331.6, + 1272.8,1330.8, + 1272.8,1331.6, + 1274.8,1334.4, + 1274,1333.6, + 1272.8,1331.6, + 1272.4,1331.6, + 1272.8,1333.2, + 1273.6,1333.6, + 1273.6,1334.8, + 1274.4,1335.2, + 1275.2,1335.2, + 1274.8,1336, + 1275.2,1338, + 1274.4,1336, + 1274,1336.4, + 1274.8,1338, + 1274.4,1339.2, + 1274.4,1341.2, + 1275.2,1341.2, + 1276.4,1344, + 1279.2,1343.6, + 1278,1344.8, + 1277.2,1344.4, + 1276.8,1344.8, + 1276.8,1344.4, + 1276.4,1344.8, + 1276.8,1345.6, + 1277.6,1345.2, + 1278.4,1346, + 1279.2,1346.4, + 1277.6,1346, + 1277.2,1346.4, + 1278,1348.4, + 1278.4,1348.8, + 1278.4,1348.8, + 1279.6,1349.2, + 1280.8,1349.2, + 1281.6,1349.6, + 1280.8,1349.2, + 1279.2,1349.6, + 1281.2,1352.8, + 1280,1351.6, + 1279.6,1351.6, + 1278.8,1350, + 1278,1349.6, + 1277.6,1349.6, + 1276,1348, + 1275.2,1346, + 1273.2,1345.2, + 1273.2,1345.2, + 1272.4,1346, + 1272.4,1346, + 1270.4,1346.8, + 1269.6,1347.6, + 1269.2,1348.8, + 1270,1349.2, + 1270.8,1349.2, + 1272.8,1350, + 1274,1349.6, + 1275.2,1349.2, + 1273.6,1349.6, + 1272.4,1350, + 1271.6,1349.6, + 1270.8,1350, + 1266.8,1350, + 1266.4,1350.4, + 1267.6,1351.6, + 1269.2,1351.6, + 1270,1352, + 1270.8,1351.6, + 1271.2,1351.2, + 1271.2,1352, + 1271.2,1351.6, + 1272.4,1352, + 1272.4,1352, + 1271.6,1353.2, + 1271.6,1353.6, + 1272.8,1353.6, + 1273.2,1353.6, + 1274,1354, + 1273.6,1354, + 1273.2,1353.6, + 1272.8,1354, + 1273.2,1354.8, + 1270.8,1355.2, + 1271.2,1354.8, + 1272,1354.8, + 1271.6,1355.2, + 1272,1357.2, + 1273.2,1357.6, + 1273.2,1357.2, + 1274,1356.4, + 1276,1356.8, + 1274.8,1356.8, + 1274,1357.2, + 1274,1357.6, + 1274,1358.4, + 1272.8,1358.8, + 1272.8,1359.2, + 1273.6,1360, + 1274.4,1360, + 1276,1358.8, + 1277.2,1359.6, + 1275.6,1359.2, + 1275.6,1360, + 1274.4,1361.2, + 1274,1361.6, + 1274.8,1361.6, + 1274.8,1362.4, + 1274.8,1362.8, + 1274.8,1363.6, + 1276,1363.6, + 1276.4,1363.6, + 1277.6,1362.4, + 1278,1362.8, + 1277.2,1362.8, + 1276.4,1364, + 1274,1364, + 1273.6,1364, + 1274.4,1365.2, + 1276.4,1366.4, + 1277.2,1367.6, + 1276,1366.4, + 1275.2,1365.2, + 1274.8,1366.4, + 1275.2,1366.4, + 1275.2,1366.8, + 1273.2,1365.6, + 1272.4,1365.6, + 1272.4,1366.8, + 1272.8,1367.2, + 1272.4,1367.2, + 1272.8,1367.6, + 1272,1368, + 1272,1369.2, + 1272.8,1370.8, + 1273.2,1370.8, + 1273.6,1370, + 1274,1370.4, + 1274.8,1369.2, + 1274.8,1369.6, + 1275.2,1369.2, + 1276.4,1370, + 1275.6,1370, + 1274.8,1370.4, + 1274.4,1370.8, + 1274.4,1370.8, + 1274,1371.6, + 1274,1372.4, + 1272.8,1372.4, + 1273.2,1374.4, + 1274.4,1374.4, + 1274.4,1374.4, + 1273.6,1374.4, + 1272.8,1375.2, + 1273.2,1376, + 1272.8,1377.6, + 1274.4,1378, + 1274.8,1377.6, + 1274.8,1376, + 1275.2,1375.2, + 1275.6,1376, + 1276,1376, + 1276,1377.6, + 1275.2,1378, + 1275.6,1379.6, + 1276,1379.2, + 1276.4,1379.6, + 1276.4,1378, + 1277.6,1378, + 1278,1379.2, + 1280.8,1377.6, + 1280.4,1378, + 1278.8,1379.6, + 1278.4,1380, + 1278.8,1380, + 1279.6,1378.8, + 1280.4,1379.2, + 1281.6,1378, + 1282.4,1377.2, + 1282.4,1377.6, + 1280.8,1379.2, + 1281.2,1379.6, + 1281.2,1379.6, + 1280,1380.4, + 1279.2,1381.2, + 1278.4,1382.4, + 1278.4,1382.4, + 1278,1382.8, + 1278,1383.6, + 1279.2,1382.8, + 1279.2,1382.8, + 1280.4,1382.8, + 1280.8,1382.8, + 1280,1384, + 1280.4,1384, + 1280,1384.4, + 1280.4,1384.4, + 1280,1384.8, + 1280,1384.8, + 1279.2,1385.6, + 1279.6,1385.6, + 1278.8,1386.8, + 1278.8,1387.6, + 1280,1386, + 1281.2,1387.2, + 1281.6,1386.4, + 1282.4,1387.2, + 1284.4,1386.4, + 1284,1386.8, + 1284.4,1387.2, + 1283.2,1387.2, + 1282,1388, + 1282.4,1388.4, + 1282,1388.4, + 1281.6,1388.8, + 1282.4,1390.4, + 1283.6,1390, + 1283.2,1390.4, + 1282.8,1390.8, + 1283.2,1390.8, + 1282.8,1391.2, + 1283.6,1391.6, + 1284.4,1391.2, + 1284,1392, + 1282.4,1392.8, + 1282.4,1393.2, + 1283.6,1393.6 +}; + + + +void make_gb_poly(agg::path_storage& ps) +{ + ps.remove_all(); + unsigned i; + const double* p = poly1; + ps.move_to(p[0], p[1]); + p += 2; + for(i = 1; i < sizeof(poly1) / sizeof(double) / 2; i++) + { + ps.line_to(p[0], p[1]); + p += 2; + } + ps.close_polygon(); + + p = poly2; + ps.move_to(p[0], p[1]); + p += 2; + for(i = 1; i < sizeof(poly2) / sizeof(double) / 2; i++) + { + ps.line_to(p[0], p[1]); + p += 2; + } + ps.close_polygon(); +} diff --git a/examples/mol_view.cpp b/examples/mol_view.cpp new file mode 100644 index 0000000..dcc63f1 --- /dev/null +++ b/examples/mol_view.cpp @@ -0,0 +1,1076 @@ +#include +#include +#include +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_scanline_p.h" +#include "agg_renderer_scanline.h" +#include "agg_conv_transform.h" +#include "agg_conv_stroke.h" +#include "agg_bspline.h" +#include "agg_ellipse.h" +#include "agg_gsv_text.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_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 }; +enum default_num_points_e { default_num_points = 20000 }; + +enum start_size_e +{ + start_width = 400, + start_height = 400 +}; + + +enum atom_color_e +{ + atom_color_general = 0, + atom_color_N = 1, + atom_color_O = 2, + atom_color_S = 3, + atom_color_P = 4, + atom_color_halogen = 5, + end_of_atom_colors +}; + + + +struct atom_type +{ + double x; + double y; + char label[4]; + int charge; + unsigned color_idx; +}; + +struct bond_type +{ + unsigned idx1; + unsigned idx2; + double x1; + double y1; + double x2; + double y2; + unsigned order; + int stereo; + int topology; +}; + + +class molecule +{ +public: + ~molecule(); + molecule(); + + bool read(FILE* fd); + + unsigned num_atoms() const { return m_num_atoms; } + unsigned num_bonds() const { return m_num_bonds; } + + const atom_type& atom(unsigned idx) const { return m_atoms[idx]; } + const bond_type& bond(unsigned idx) const { return m_bonds[idx]; } + + double average_bond_len() const { return m_avr_len; } + + const char* name() const { return m_name; } + + static int get_int(const char* buf, int pos, int len); + static double get_dbl(const char* buf, int pos, int len); + static char* get_str(char* dst, const char* buf, int pos, int len); + +private: + atom_type* m_atoms; + unsigned m_num_atoms; + bond_type* m_bonds; + unsigned m_num_bonds; + char m_name[128]; + double m_avr_len; +}; + + + + +molecule::~molecule() +{ + delete [] m_bonds; + delete [] m_atoms; +} + + + + +molecule::molecule() : + m_atoms(0), + m_num_atoms(0), + m_bonds(0), + m_num_bonds(0), + m_avr_len(0) +{ + m_name[0] = 0; +} + + +int molecule::get_int(const char* buf, int pos, int len) +{ + char tmp[32]; + return atoi(get_str(tmp, buf, pos, len)); +} + +double molecule::get_dbl(const char* buf, int pos, int len) +{ + char tmp[32]; + return atof(get_str(tmp, buf, pos, len)); +} + +char* molecule::get_str(char* dst, const char* buf, int pos, int len) +{ + --pos; + int buf_len = strlen(buf); + buf += pos; + while(pos + len < buf_len && isspace(*buf)) + { + ++buf; + --len; + } + if(len >= 0) + { + if(len > 0) memcpy(dst, buf, len); + dst[len] = 0; + } + + char* ts = dst; + while(*ts && !isspace(*ts)) ts++; + *ts = 0; + return dst; +} + + +unsigned trim_cr_lf(char* buf) +{ + unsigned len = strlen(buf); + + // Trim "\n\r" at the beginning + unsigned pos = 0; + while(len && (buf[0] == '\n' || buf[0] == '\r')) + { + --len; + ++pos; + } + // Note that strcpy has undefined behavior if the strings overlap + if(pos) memmove(buf, buf + pos, len); + + // Trim "\n\r" at the end + while(len && (buf[len-1] == '\n' || buf[len-1] == '\r')) --len; + buf[len] = 0; + return len; +} + + +/* +MFCD00191150 + Mt7.00 09020210442D + + 23 23 0 0 1 0 0 0 0 0999 V2000 + -2.6793 -0.2552 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 + . . . + 1 2 1 0 0 0 0 + . . . +M END +> +MFCD00191150 + +$$$$ +*/ +bool molecule::read(FILE* fd) +{ + char buf[512]; + unsigned len; + if(!fgets(buf, 510, fd)) return false; + len = trim_cr_lf(buf); + if(len > 127) len = 127; + + if(len) memcpy(m_name, buf, len); + m_name[len] = 0; + + if(!fgets(buf, 510, fd)) return false; + if(!fgets(buf, 510, fd)) return false; + if(!fgets(buf, 510, fd)) return false; + trim_cr_lf(buf); + m_num_atoms = get_int(buf, 1, 3); + m_num_bonds = get_int(buf, 4, 3); + if(m_num_atoms == 0 || m_num_bonds == 0) return false; + m_atoms = new atom_type[m_num_atoms]; + m_bonds = new bond_type[m_num_bonds]; + memset(m_atoms, 0, sizeof(atom_type) * m_num_atoms); + memset(m_bonds, 0, sizeof(bond_type) * m_num_bonds); + + unsigned i; + for(i = 0; i < m_num_atoms; i++) + { + if(!fgets(buf, 510, fd)) return false; + trim_cr_lf(buf); +/* + -2.6793 -0.2552 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0 +*/ + m_atoms[i].x = get_dbl(buf, 1, 10); + m_atoms[i].y = get_dbl(buf, 11, 10); + get_str(m_atoms[i].label, buf, 32, 3); + m_atoms[i].charge = get_int(buf, 39, 1); + if(m_atoms[i].charge) m_atoms[i].charge = 4 - m_atoms[i].charge; + + if(strcmp(m_atoms[i].label, "N") == 0) m_atoms[i].color_idx = atom_color_N; + if(strcmp(m_atoms[i].label, "O") == 0) m_atoms[i].color_idx = atom_color_O; + if(strcmp(m_atoms[i].label, "S") == 0) m_atoms[i].color_idx = atom_color_S; + if(strcmp(m_atoms[i].label, "P") == 0) m_atoms[i].color_idx = atom_color_P; + if(strcmp(m_atoms[i].label, "F") == 0 || + strcmp(m_atoms[i].label, "Cl") == 0 || + strcmp(m_atoms[i].label, "Br") == 0 || + strcmp(m_atoms[i].label, "I") == 0) m_atoms[i].color_idx = atom_color_halogen; + } + + m_avr_len = 0.0; + for(i = 0; i < m_num_bonds; i++) + { + if(!fgets(buf, 510, fd)) return false; + trim_cr_lf(buf); +/* + 1 2 1 0 0 0 0 +*/ + m_bonds[i].idx1 = get_int(buf, 1, 3) - 1; + m_bonds[i].idx2 = get_int(buf, 4, 3) - 1; + + if(m_bonds[i].idx1 >= m_num_atoms || m_bonds[i].idx2 >= m_num_atoms) return false; + + m_bonds[i].x1 = m_atoms[m_bonds[i].idx1].x; + m_bonds[i].y1 = m_atoms[m_bonds[i].idx1].y; + m_bonds[i].x2 = m_atoms[m_bonds[i].idx2].x; + m_bonds[i].y2 = m_atoms[m_bonds[i].idx2].y; + m_bonds[i].order = get_int(buf, 7, 3); + m_bonds[i].stereo = get_int(buf, 10, 3); + m_bonds[i].topology = get_int(buf, 13, 3); + + m_avr_len += sqrt((m_bonds[i].x1 - m_bonds[i].x2) * (m_bonds[i].x1 - m_bonds[i].x2) + + (m_bonds[i].y1 - m_bonds[i].y2) * (m_bonds[i].y1 - m_bonds[i].y2)); + } + m_avr_len /= double(m_num_bonds); + + while(fgets(buf, 510, fd)) + { + trim_cr_lf(buf); + if(buf[0] == '$') return true; + } + + return false; +} + + + +namespace agg +{ + class line + { + public: + line() : + m_x1(0.0), m_y1(0.0), m_x2(1.0), m_y2(0.0), m_thickness(0.1) + { + } + + line(double x1, double y1, double x2, double y2, double thickness) : + m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2), m_thickness(thickness) + { + } + + void init(double x1, double y1, double x2, double y2) + { + m_x1 = x1; + m_y1 = y1; + m_x2 = x2; + m_y2 = y2; + } + + void thickness(double th) + { + m_thickness = th; + } + + void rewind(unsigned start); + unsigned vertex(double* x, double* y); + + private: + double m_x1; + double m_y1; + double m_x2; + double m_y2; + double m_dx; + double m_dy; + double m_thickness; + unsigned m_vertex; + }; + + + + inline void line::rewind(unsigned) + { + calc_orthogonal(m_thickness*0.5, m_x1, m_y1, m_x2, m_y2, &m_dx, &m_dy); + m_vertex = 0; + } + + + + inline unsigned line::vertex(double* x, double* y) + { + switch(m_vertex) + { + case 0: + *x = m_x1 - m_dx; + *y = m_y1 - m_dy; + m_vertex++; + return path_cmd_move_to; + + case 1: + *x = m_x2 - m_dx; + *y = m_y2 - m_dy; + m_vertex++; + return path_cmd_line_to; + + case 2: + *x = m_x2 + m_dx; + *y = m_y2 + m_dy; + m_vertex++; + return path_cmd_line_to; + + case 3: + *x = m_x1 + m_dx; + *y = m_y1 + m_dy; + m_vertex++; + return path_cmd_line_to; + } + return path_cmd_stop; + } + + + + class solid_wedge + { + public: + solid_wedge() : + m_x1(0.0), m_y1(0.0), m_x2(1.0), m_y2(0.0), m_thickness(0.1) + { + } + + solid_wedge(double x1, double y1, double x2, double y2, double thickness) : + m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2), m_thickness(thickness) + { + } + + void init(double x1, double y1, double x2, double y2) + { + m_x1 = x1; + m_y1 = y1; + m_x2 = x2; + m_y2 = y2; + } + + void thickness(double th) + { + m_thickness = th; + } + + void rewind(unsigned start); + unsigned vertex(double* x, double* y); + + private: + double m_x1; + double m_y1; + double m_x2; + double m_y2; + double m_dx; + double m_dy; + double m_thickness; + unsigned m_vertex; + }; + + + + inline void solid_wedge::rewind(unsigned) + { + calc_orthogonal(m_thickness*2.0, m_x1, m_y1, m_x2, m_y2, &m_dx, &m_dy); + m_vertex = 0; + } + + + + inline unsigned solid_wedge::vertex(double* x, double* y) + { + switch(m_vertex) + { + case 0: + *x = m_x1; + *y = m_y1; + m_vertex++; + return path_cmd_move_to; + + case 1: + *x = m_x2 - m_dx; + *y = m_y2 - m_dy; + m_vertex++; + return path_cmd_line_to; + + case 2: + *x = m_x2 + m_dx; + *y = m_y2 + m_dy; + m_vertex++; + return path_cmd_line_to; + } + return path_cmd_stop; + } + + + + + + + + + + class dashed_wedge + { + public: + dashed_wedge() : + m_x1(0.0), m_y1(0.0), m_x2(1.0), m_y2(0.0), + m_thickness(0.1), + m_num_dashes(8) + { + } + + dashed_wedge(double x1, double y1, double x2, double y2, + double thickness, unsigned num_dashes=8) : + m_x1(x2), m_y1(y2), m_x2(x1), m_y2(y1), + m_thickness(thickness), + m_num_dashes(num_dashes) + { + } + + void init(double x1, double y1, double x2, double y2) + { + m_x1 = x2; + m_y1 = y2; + m_x2 = x1; + m_y2 = y1; + } + + void num_dashes(unsigned nd) + { + m_num_dashes = nd; + } + + void thickness(double th) + { + m_thickness = th; + } + + void rewind(unsigned start); + unsigned vertex(double* x, double* y); + + private: + double m_x1; + double m_y1; + double m_x2; + double m_y2; + double m_xt2; + double m_yt2; + double m_xt3; + double m_yt3; + double m_xd[4]; + double m_yd[4]; + double m_thickness; + unsigned m_num_dashes; + unsigned m_vertex; + }; + + + + void dashed_wedge::rewind(unsigned) + { + double dx; + double dy; + calc_orthogonal(m_thickness*2.0, m_x1, m_y1, m_x2, m_y2, &dx, &dy); + m_xt2 = m_x2 - dx; + m_yt2 = m_y2 - dy; + m_xt3 = m_x2 + dx; + m_yt3 = m_y2 + dy; + m_vertex = 0; + } + + + unsigned dashed_wedge::vertex(double* x, double* y) + { + if(m_vertex < m_num_dashes * 4) + { + if((m_vertex % 4) == 0) + { + double k1 = double(m_vertex / 4) / double(m_num_dashes); + double k2 = k1 + 0.4 / double(m_num_dashes); + + m_xd[0] = m_x1 + (m_xt2 - m_x1) * k1; + m_yd[0] = m_y1 + (m_yt2 - m_y1) * k1; + m_xd[1] = m_x1 + (m_xt2 - m_x1) * k2; + m_yd[1] = m_y1 + (m_yt2 - m_y1) * k2; + m_xd[2] = m_x1 + (m_xt3 - m_x1) * k2; + m_yd[2] = m_y1 + (m_yt3 - m_y1) * k2; + m_xd[3] = m_x1 + (m_xt3 - m_x1) * k1; + m_yd[3] = m_y1 + (m_yt3 - m_y1) * k1; + *x = m_xd[0]; + *y = m_yd[0]; + m_vertex++; + return path_cmd_move_to; + } + else + { + *x = m_xd[m_vertex % 4]; + *y = m_yd[m_vertex % 4]; + m_vertex++; + return path_cmd_line_to; + } + } + return path_cmd_stop; + } + + + + + + + + + + + +} + + + + + + +class bond_vertex_generator +{ + enum bond_style_e + { + bond_single, + bond_wedged_solid, + bond_wedged_dashed, + bond_double, + bond_double_left, + bond_double_right, + bond_triple + }; + +public: + bond_vertex_generator(const bond_type& bond, double thickness) : + m_bond(bond), + m_thickness(thickness), + m_style(bond_single) + { + if(bond.order == 1) + { + if(bond.stereo == 1) m_style = bond_wedged_solid; + if(bond.stereo == 6) m_style = bond_wedged_dashed; + } + if(bond.order == 2) + { + m_style = bond_double; + if(bond.topology == 1) m_style = bond_double_left; + if(bond.topology == 2) m_style = bond_double_right; + } + if(bond.order == 3) m_style = bond_triple; + m_line1.thickness(thickness); + m_line2.thickness(thickness); + m_line3.thickness(thickness); + m_solid_wedge.thickness(thickness); + m_dashed_wedge.thickness(thickness); + } + + void rewind(unsigned) + { + double dx, dy, dx1, dy1, dx2, dy2; + + switch(m_style) + { + case bond_wedged_solid: + m_solid_wedge.init(m_bond.x1, m_bond.y1, m_bond.x2, m_bond.y2); + m_solid_wedge.rewind(0); + break; + + case bond_wedged_dashed: + m_dashed_wedge.init(m_bond.x1, m_bond.y1, m_bond.x2, m_bond.y2); + m_dashed_wedge.rewind(0); + break; + + case bond_double: + case bond_double_left: + case bond_double_right: + agg::calc_orthogonal(m_thickness, + m_bond.x1, m_bond.y1, + m_bond.x2, m_bond.y2, + &dx, &dy); + dx1 = dy1 = 0; + + // To Do: ring perception and the proper drawing + // of the double bonds in the aromatic rings. + //if(m_style == bond_double) + { + dx1 = dx2 = dx; + dy1 = dy2 = dy; + } +/* + else if(m_style == bond_double_left) + { + dx2 = dx * 2.0; + dy2 = dy * 2.0; + } + else + { + dx2 = -dx * 2.0; + dy2 = -dy * 2.0; + } +*/ + + m_line1.init(m_bond.x1 - dx1, + m_bond.y1 - dy1, + m_bond.x2 - dx1, + m_bond.y2 - dy1); + m_line1.rewind(0); + + m_line2.init(m_bond.x1 + dx2, + m_bond.y1 + dy2, + m_bond.x2 + dx2, + m_bond.y2 + dy2); + m_line2.rewind(0); + m_status = 0; + break; + + case bond_triple: + // To Do: triple bonds drawing. + + default: + m_line1.init(m_bond.x1, m_bond.y1, m_bond.x2, m_bond.y2); + m_line1.rewind(0); + break; + } + } + + + unsigned vertex(double* x, double* y) + { + unsigned flag = agg::path_cmd_stop; + switch(m_style) + { + case bond_wedged_solid: + return m_solid_wedge.vertex(x, y); + + case bond_wedged_dashed: + return m_dashed_wedge.vertex(x, y); + + case bond_double_left: + case bond_double_right: + case bond_double: + if(m_status == 0) + { + flag = m_line1.vertex(x, y); + if(flag == agg::path_cmd_stop) + { + m_status = 1; + } + } + + if(m_status == 1) + { + flag = m_line2.vertex(x, y); + } + return flag; + + case bond_triple: + case bond_single: + break; + } + return m_line1.vertex(x, y); + } + + + +private: + bond_vertex_generator(const bond_vertex_generator&); + const bond_vertex_generator& operator = (const bond_vertex_generator&); + + const bond_type& m_bond; + double m_thickness; + bond_style_e m_style; + agg::line m_line1; + agg::line m_line2; + agg::line m_line3; + agg::solid_wedge m_solid_wedge; + agg::dashed_wedge m_dashed_wedge; + unsigned m_status; +}; + + + + + + + + + + + +class the_application : public agg::platform_support +{ + molecule* m_molecules; + unsigned m_num_molecules; + unsigned m_cur_molecule; + agg::slider_ctrl m_thickness; + agg::slider_ctrl m_text_size; + 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; + bool m_mouse_move; + agg::srgba8 m_atom_colors[end_of_atom_colors]; + + +public: + virtual ~the_application() + { + delete [] m_molecules; + } + + the_application(agg::pix_format_e format, bool flip_y, const char* fname) : + agg::platform_support(format, flip_y), + m_molecules(new molecule [100]), + m_num_molecules(0), + m_cur_molecule(0), + m_thickness(5, 5, start_width-5, 12), + m_text_size(5, 20, start_width-5, 27), + m_pdx(0.0), + m_pdy(0.0), + m_center_x(start_width / 2), + m_center_y(start_height / 2), + m_scale(1.0), + m_prev_scale(1.0), + m_angle(0.0), + m_prev_angle(0.0), + m_mouse_move(false) + { + m_thickness.label("Thickness=%3.2f"); + m_text_size.label("Label Size=%3.2f"); + add_ctrl(m_thickness); + add_ctrl(m_text_size); + + FILE* fd = fopen(full_file_name(fname), "r"); + if(fd) + { + unsigned i; + for(i = 0; i < 100; i++) + { + if(!m_molecules[m_num_molecules].read(fd)) break; + m_num_molecules++; + } + fclose(fd); + } + else + { + char buf[256]; + sprintf(buf, "File not found: '%s'. Copy from ../art/%s\n", + fname, fname); + message(buf); + } + memset(m_atom_colors, 0, sizeof(agg::srgba8) * end_of_atom_colors); + m_atom_colors[atom_color_general] = agg::srgba8(0,0,0); + m_atom_colors[atom_color_N] = agg::srgba8(0,0,120); + m_atom_colors[atom_color_O] = agg::srgba8(200,0,0); + m_atom_colors[atom_color_S] = agg::srgba8(120,120,0); + m_atom_colors[atom_color_P] = agg::srgba8(80,50,0); + m_atom_colors[atom_color_halogen] = agg::srgba8(0,200,0); + } + + + virtual void on_init() + { + } + + + virtual void on_draw() + { + double width = initial_width(); + double height = initial_height(); + + agg::rasterizer_scanline_aa<> ras; + agg::scanline_p8 sl; + + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_solid; + + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_solid rs(rb); + + ras.clip_box(0, 0, rb.width(), rb.height()); + + rb.clear(agg::rgba(1,1,1)); + + const molecule& mol = m_molecules[m_cur_molecule]; + unsigned i; + double min_x = 1e100; + double max_x = -1e100; + double min_y = 1e100; + double max_y = -1e100; + + for(i = 0; i < mol.num_atoms(); i++) + { + if(mol.atom(i).x < min_x) min_x = mol.atom(i).x; + if(mol.atom(i).y < min_y) min_y = mol.atom(i).y; + if(mol.atom(i).x > max_x) max_x = mol.atom(i).x; + if(mol.atom(i).y > max_y) max_y = mol.atom(i).y; + } + + agg::trans_affine mtx; + + mtx *= agg::trans_affine_translation(-(max_x + min_x) * 0.5, -(max_y + min_y) * 0.5); + + double scale = width / (max_x - min_x); + double t = height / (max_y - min_y); + if(scale > t) scale = t; + + double text_size = mol.average_bond_len() * m_text_size.value() / 4.0; + double thickness = mol.average_bond_len() / + sqrt(m_scale < 0.0001 ? 0.0001 : m_scale) / + 8.0; + + mtx *= agg::trans_affine_scaling(scale*0.80, scale*0.80); + mtx *= agg::trans_affine_rotation(m_angle); + mtx *= agg::trans_affine_scaling(m_scale, m_scale); + mtx *= agg::trans_affine_translation(m_center_x, m_center_y); + mtx *= trans_affine_resizing(); + + rs.color(agg::rgba(0,0,0)); + for(i = 0; i < mol.num_bonds(); i++) + { + bond_vertex_generator bond(mol.bond(i), + m_thickness.value() * thickness); + agg::conv_transform tr(bond, mtx); + ras.add_path(tr); + agg::render_scanlines(ras, sl, rs); + } + + + agg::ellipse ell; + agg::conv_transform tr(ell, mtx); + for(i = 0; i < mol.num_atoms(); i++) + { + if(strcmp(mol.atom(i).label, "C") != 0) + { + ell.init(mol.atom(i).x, + mol.atom(i).y, + text_size * 2.5, + text_size * 2.5, + 20); + ras.add_path(tr); + rs.color(agg::rgba(1.0, 1.0, 1.0)); + agg::render_scanlines(ras, sl, rs); + } + } + + + text_size *= 3.0; + + + agg::gsv_text label; + agg::conv_stroke ls(label); + agg::conv_transform > lo(ls, mtx); + ls.line_join(agg::round_join); + ls.line_cap(agg::round_cap); + ls.approximation_scale(mtx.scale()); + for(i = 0; i < mol.num_atoms(); i++) + { + if(strcmp(mol.atom(i).label, "C") != 0) + { + ls.width(m_thickness.value() * thickness); + label.text(mol.atom(i).label); + label.start_point(mol.atom(i).x - text_size/2, mol.atom(i).y - text_size/2); + label.size(text_size); + ras.add_path(lo); + rs.color(m_atom_colors[mol.atom(i).color_idx]); + agg::render_scanlines(ras, sl, rs); + } + } + + + ls.approximation_scale(1.0); + agg::conv_transform > name(ls, trans_affine_resizing()); + ls.width(1.5); + label.text(mol.name()); + label.size(10.0); + label.start_point(10.0, start_height - 20.0); + ras.reset(); + ras.add_path(name); + rs.color(agg::rgba(0,0,0)); + agg::render_scanlines(ras, sl, rs); + + + + agg::render_ctrl(ras, sl, rb, m_thickness); + agg::render_ctrl(ras, sl, rb, m_text_size); + } + + + + + + + + + + + + + + + virtual void on_idle() + { + m_angle += agg::deg2rad(0.1); + 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; + force_redraw(); + } + + + + + + virtual void on_mouse_button_up(int x, int y, unsigned flags) + { + m_mouse_move = false; + } + + virtual void on_mouse_move(int x, int y, unsigned flags) + { + double x2 = x; + double y2 = y; + trans_affine_resizing().inverse_transform(&x2, &y2); + + if(m_mouse_move && (flags & agg::mouse_left) != 0) + { + 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(); + } + + if(m_mouse_move && (flags & agg::mouse_right) != 0) + { + m_center_x = x2 + m_pdx; + m_center_y = y2 + m_pdy; + force_redraw(); + } + + } + + + + + + + + virtual void on_key(int, int, unsigned key, unsigned) + { + switch(key) + { + case agg::key_left: + case agg::key_up: + case agg::key_page_up: + if(m_cur_molecule) --m_cur_molecule; + force_redraw(); + break; + + case agg::key_right: + case agg::key_down: + case agg::key_page_down: + if(m_cur_molecule < m_num_molecules - 1) ++m_cur_molecule; + force_redraw(); + break; + + case ' ': + wait_mode(!wait_mode()); + break; + } + } + +}; + + + + + +int agg_main(int argc, char* argv[]) +{ + const char* fname = "1.sdf"; + if(argc > 1) + { + fname = argv[1]; + } + + + the_application app(pix_format, flip_y, fname); + app.caption("AGG - A Simple SDF Molecular Viewer"); + + if(app.init(start_width, start_height, agg::window_resize)) + { + return app.run(); + } + + return 1; +} + + diff --git a/examples/multi_clip.cpp b/examples/multi_clip.cpp new file mode 100644 index 0000000..f0c8cc3 --- /dev/null +++ b/examples/multi_clip.cpp @@ -0,0 +1,374 @@ +#include +#include +#include +#include "agg_basics.h" +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_scanline_u.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_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_ellipse.h" +#include "ctrl/agg_slider_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_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_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 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 + { + 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 + { + 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 m_num_cb; + +public: + 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) + { + parse_lion(); + add_ctrl(m_num_cb); + m_num_cb.range(2, 10); + //m_num_cb.num_steps(8); + m_num_cb.label("N=%.2f"); + m_num_cb.no_transform(); + } + + virtual void on_draw() + { + unsigned i; + int width = rbuf_window().width(); + int height = rbuf_window().height(); + + pixfmt pf(rbuf_window()); + typedef agg::renderer_mclip base_ren_type; + + base_ren_type r(pf); + agg::renderer_scanline_aa_solid rs(r); + + 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); + + r.clear(agg::rgba(1, 1, 1)); + + + r.reset_clipping(false); // Visibility: "false" means "no visible regions" + int x, y; + double n = m_num_cb.value(); + for(x = 0; x < n; x++) + { + for(y = 0; y < n; y++) + { + int x1 = int(width * x / n); + int y1 = int(height * y / n); + int x2 = int(width * (x + 1) / n); + int y2 = int(height * (y + 1) / n); + r.add_clip_box(x1 + 5, y1 + 5, x2 - 5, y2 - 5); + } + } + + + + // Render the lion + agg::conv_transform trans(g_path, mtx); + agg::render_all_paths(g_rasterizer, g_scanline, rs, trans, g_colors, g_path_idx, g_npaths); + + +// The scanline rasterizer allows you to perform clipping to multiple +// regions "manually", like in the following code, but the "embedded" method +// shows much better performance. +// +//for(i = 0; i < g_npaths; i++) +//{ +// g_rasterizer.reset(); +// g_rasterizer.add_path(trans, g_path_idx[i]); +// rs.color(g_colors[i]); +// +// int x, y; +// double n = m_num_cb.value(); +// for(x = 0; x < n; x++) +// { +// for(y = 0; y < n; y++) +// { +// int x1 = int(width * x / n); +// int y1 = int(height * y / n); +// int x2 = int(width * (x + 1) / n); +// int y2 = int(height * (y + 1) / n); +// // r should be of type renderer_base<> +// r.clip_box(agg::rect_i(x1 + 5, y1 + 5, x2 - 5, y2 - 5)); +// agg::render_scanlines(g_rasterizer, g_scanline, rs); +// } +// } +//} + + + + // Render random Bresenham lines and markers + agg::renderer_markers 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 renderer_type; + renderer_type ren(r, profile); + + typedef agg::rasterizer_outline_aa 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, + (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 grad_color; + typedef agg::gradient_circle grad_func; + typedef agg::span_interpolator_linear<> interpolator_type; + typedef agg::span_gradient 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 sa; + interpolator_type inter(grm); + span_grad_type sg(inter, grf, grc, 0, 10); + for(i = 0; i < 50; i++) + { + x = rand() % width; + y = rand() % height; + double radius = rand() % 10 + 5; + grm.reset(); + grm *= agg::trans_affine_scaling(radius / 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, radius, radius, 32); + g_rasterizer.add_path(ell); + agg::render_scanlines_aa(g_rasterizer, g_scanline, r, sa, sg); + } + + r.reset_clipping(true); // "true" means "all rendering buffer is visible". + agg::render_ctrl(g_rasterizer, g_scanline, r, 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; +} + + + + + + diff --git a/examples/parse_lion.cpp b/examples/parse_lion.cpp new file mode 100644 index 0000000..25c0a43 --- /dev/null +++ b/examples/parse_lion.cpp @@ -0,0 +1,215 @@ +#include +#include +#include +#include "agg_color_rgba.h" +#include "agg_path_storage.h" +#include "agg_bounding_rect.h" + +static char g_lion[] = +"f2cc99\n" +"M 69,18 L 82,8 L 99,3 L 118,5 L 135,12 L 149,21 L 156,13 L 165,9 L 177,13 L 183,28 L 180,50 L 164,91 L 155,107 L 154,114 L 151,121 L 141,127 L 139,136 L 155,206 L 157,251 L 126,342 L 133,357 L 128,376 L 83,376 L 75,368 L 67,350 L 61,350 L 53,369 L 4,369 L 2,361 L 5,354 L 12,342 L 16,321 L 4,257 L 4,244 L 7,218 L 9,179 L 26,127 L 43,93 L 32,77 L 30,70 L 24,67 L 16,49 L 17,35 L 18,23 L 30,12 L 40,7 L 53,7 L 62,12 L 69,18 L 69,18 L 69,18\n" +"e5b27f\n" +"M 142,79 L 136,74 L 138,82 L 133,78 L 133,84 L 127,78 L 128,85 L 124,80 L 125,87 L 119,82 L 119,90 L 125,99 L 125,96 L 128,100 L 128,94 L 131,98 L 132,93 L 135,97 L 136,93 L 138,97 L 139,94 L 141,98 L 143,94 L 144,85 L 142,79 L 142,79 L 142,79\n" +"eb8080\n" +"M 127,101 L 132,100 L 137,99 L 144,101 L 143,105 L 135,110 L 127,101 L 127,101 L 127,101\n" +"f2cc99\n" +"M 178,229 L 157,248 L 139,296 L 126,349 L 137,356 L 158,357 L 183,342 L 212,332 L 235,288 L 235,261 L 228,252 L 212,250 L 188,251 L 178,229 L 178,229 L 178,229\n" +"9c826b\n" +"M 56,229 L 48,241 L 48,250 L 57,281 L 63,325 L 71,338 L 81,315 L 76,321 L 79,311 L 83,301 L 75,308 L 80,298 L 73,303 L 76,296 L 71,298 L 74,292 L 69,293 L 74,284 L 78,278 L 71,278 L 74,274 L 68,273 L 70,268 L 66,267 L 68,261 L 60,266 L 62,259 L 65,253 L 57,258 L 59,251 L 55,254 L 55,248 L 60,237 L 54,240 L 58,234 L 54,236 L 56,229 L 56,229 L 56,229\n" +"M 74,363 L 79,368 L 81,368 L 85,362 L 89,363 L 92,370 L 96,373 L 101,372 L 108,361 L 110,371 L 113,373 L 116,371 L 120,358 L 122,363 L 123,371 L 126,371 L 129,367 L 132,357 L 135,361 L 130,376 L 127,377 L 94,378 L 84,376 L 76,371 L 74,363 L 74,363 L 74,363\n" +"M 212,250 L 219,251 L 228,258 L 236,270 L 235,287 L 225,304 L 205,332 L 177,343 L 171,352 L 158,357 L 166,352 L 168,346 L 168,339 L 165,333 L 155,327 L 155,323 L 161,320 L 165,316 L 169,316 L 167,312 L 171,313 L 168,308 L 173,309 L 170,306 L 177,306 L 175,308 L 177,311 L 174,311 L 176,316 L 171,315 L 174,319 L 168,320 L 168,323 L 175,327 L 179,332 L 183,326 L 184,332 L 189,323 L 190,328 L 194,320 L 194,325 L 199,316 L 201,320 L 204,313 L 206,316 L 208,310 L 211,305 L 219,298 L 226,288 L 229,279 L 228,266 L 224,259 L 217,253 L 212,250 L 212,250 L 212,250\n" +"M 151,205 L 151,238 L 149,252 L 141,268 L 128,282 L 121,301 L 130,300 L 126,313 L 118,324 L 116,337 L 120,346 L 133,352 L 133,340 L 137,333 L 145,329 L 156,327 L 153,319 L 153,291 L 157,271 L 170,259 L 178,277 L 193,250 L 174,216 L 151,205 L 151,205 L 151,205\n" +"M 78,127 L 90,142 L 95,155 L 108,164 L 125,167 L 139,175 L 150,206 L 152,191 L 141,140 L 121,148 L 100,136 L 78,127 L 78,127 L 78,127\n" +"M 21,58 L 35,63 L 38,68 L 32,69 L 42,74 L 40,79 L 47,80 L 54,83 L 45,94 L 34,81 L 32,73 L 24,66 L 21,58 L 21,58 L 21,58\n" +"M 71,34 L 67,34 L 66,27 L 59,24 L 54,17 L 48,17 L 39,22 L 30,26 L 28,31 L 31,39 L 38,46 L 29,45 L 36,54 L 41,61 L 41,70 L 50,69 L 54,71 L 55,58 L 67,52 L 76,43 L 76,39 L 68,44 L 71,34 L 71,34 L 71,34\n" +"M 139,74 L 141,83 L 143,89 L 144,104 L 148,104 L 155,106 L 154,86 L 157,77 L 155,72 L 150,77 L 144,77 L 139,74 L 139,74 L 139,74\n" +"M 105,44 L 102,53 L 108,58 L 111,62 L 112,55 L 105,44 L 105,44 L 105,44\n" +"M 141,48 L 141,54 L 144,58 L 139,62 L 137,66 L 136,59 L 137,52 L 141,48 L 141,48 L 141,48\n" +"M 98,135 L 104,130 L 105,134 L 108,132 L 108,135 L 112,134 L 113,137 L 116,136 L 116,139 L 119,139 L 124,141 L 128,140 L 133,138 L 140,133 L 139,140 L 126,146 L 104,144 L 98,135 L 98,135 L 98,135\n" +"M 97,116 L 103,119 L 103,116 L 111,118 L 116,117 L 122,114 L 127,107 L 135,111 L 142,107 L 141,114 L 145,118 L 149,121 L 145,125 L 140,124 L 127,121 L 113,125 L 100,124 L 97,116 L 97,116 L 97,116\n" +"M 147,33 L 152,35 L 157,34 L 153,31 L 160,31 L 156,28 L 161,28 L 159,24 L 163,25 L 163,21 L 165,22 L 170,23 L 167,17 L 172,21 L 174,18 L 175,23 L 176,22 L 177,28 L 177,33 L 174,37 L 176,39 L 174,44 L 171,49 L 168,53 L 164,57 L 159,68 L 156,70 L 154,60 L 150,51 L 146,43 L 144,35 L 147,33 L 147,33 L 147,33\n" +"M 85,72 L 89,74 L 93,75 L 100,76 L 105,75 L 102,79 L 94,79 L 88,76 L 85,72 L 85,72 L 85,72\n" +"M 86,214 L 79,221 L 76,232 L 82,225 L 78,239 L 82,234 L 78,245 L 81,243 L 79,255 L 84,250 L 84,267 L 87,254 L 90,271 L 90,257 L 95,271 L 93,256 L 95,249 L 92,252 L 93,243 L 89,253 L 89,241 L 86,250 L 87,236 L 83,245 L 87,231 L 82,231 L 90,219 L 84,221 L 86,214 L 86,214 L 86,214\n" +"ffcc7f\n" +"M 93,68 L 96,72 L 100,73 L 106,72 L 108,66 L 105,63 L 100,62 L 93,68 L 93,68 L 93,68\n" +"M 144,64 L 142,68 L 142,73 L 146,74 L 150,73 L 154,64 L 149,62 L 144,64 L 144,64 L 144,64\n" +"9c826b\n" +"M 57,91 L 42,111 L 52,105 L 41,117 L 53,112 L 46,120 L 53,116 L 50,124 L 57,119 L 55,127 L 61,122 L 60,130 L 67,126 L 66,134 L 71,129 L 72,136 L 77,130 L 76,137 L 80,133 L 82,138 L 86,135 L 96,135 L 94,129 L 86,124 L 83,117 L 77,123 L 79,117 L 73,120 L 75,112 L 68,116 L 71,111 L 65,114 L 69,107 L 63,110 L 68,102 L 61,107 L 66,98 L 61,103 L 63,97 L 57,99 L 57,91 L 57,91 L 57,91\n" +"M 83,79 L 76,79 L 67,82 L 75,83 L 65,88 L 76,87 L 65,92 L 76,91 L 68,96 L 77,95 L 70,99 L 80,98 L 72,104 L 80,102 L 76,108 L 85,103 L 92,101 L 87,98 L 93,96 L 86,94 L 91,93 L 85,91 L 93,89 L 99,89 L 105,93 L 107,85 L 102,82 L 92,80 L 83,79 L 83,79 L 83,79\n" +"M 109,77 L 111,83 L 109,89 L 113,94 L 117,90 L 117,81 L 114,78 L 109,77 L 109,77 L 109,77\n" +"M 122,128 L 127,126 L 134,127 L 136,129 L 134,130 L 130,128 L 124,129 L 122,128 L 122,128 L 122,128\n" +"M 78,27 L 82,32 L 80,33 L 82,36 L 78,37 L 82,40 L 78,42 L 81,46 L 76,47 L 78,49 L 74,50 L 82,52 L 87,50 L 83,48 L 91,46 L 86,45 L 91,42 L 88,40 L 92,37 L 86,34 L 90,31 L 86,29 L 89,26 L 78,27 L 78,27 L 78,27\n" +"M 82,17 L 92,20 L 79,21 L 90,25 L 81,25 L 94,28 L 93,26 L 101,30 L 101,26 L 107,33 L 108,28 L 111,40 L 113,34 L 115,45 L 117,39 L 119,54 L 121,46 L 124,58 L 126,47 L 129,59 L 130,49 L 134,58 L 133,44 L 137,48 L 133,37 L 137,40 L 133,32 L 126,20 L 135,26 L 132,19 L 138,23 L 135,17 L 142,18 L 132,11 L 116,6 L 94,6 L 78,11 L 92,12 L 80,14 L 90,16 L 82,17 L 82,17 L 82,17\n" +"M 142,234 L 132,227 L 124,223 L 115,220 L 110,225 L 118,224 L 127,229 L 135,236 L 122,234 L 115,237 L 113,242 L 121,238 L 139,243 L 121,245 L 111,254 L 95,254 L 102,244 L 104,235 L 110,229 L 100,231 L 104,224 L 113,216 L 122,215 L 132,217 L 141,224 L 145,230 L 149,240 L 142,234 L 142,234 L 142,234\n" +"M 115,252 L 125,248 L 137,249 L 143,258 L 134,255 L 125,254 L 115,252 L 115,252 L 115,252\n" +"M 114,212 L 130,213 L 140,219 L 147,225 L 144,214 L 137,209 L 128,207 L 114,212 L 114,212 L 114,212\n" +"M 102,263 L 108,258 L 117,257 L 131,258 L 116,260 L 109,265 L 102,263 L 102,263 L 102,263\n" +"M 51,241 L 35,224 L 40,238 L 23,224 L 31,242 L 19,239 L 28,247 L 17,246 L 25,250 L 37,254 L 39,263 L 44,271 L 47,294 L 48,317 L 51,328 L 60,351 L 60,323 L 53,262 L 47,246 L 51,241 L 51,241 L 51,241\n" +"M 2,364 L 9,367 L 14,366 L 18,355 L 20,364 L 26,366 L 31,357 L 35,364 L 39,364 L 42,357 L 47,363 L 53,360 L 59,357 L 54,369 L 7,373 L 2,364 L 2,364 L 2,364\n" +"M 7,349 L 19,345 L 25,339 L 18,341 L 23,333 L 28,326 L 23,326 L 27,320 L 23,316 L 25,311 L 20,298 L 15,277 L 12,264 L 9,249 L 10,223 L 3,248 L 5,261 L 15,307 L 17,326 L 11,343 L 7,349 L 7,349 L 7,349\n" +"M 11,226 L 15,231 L 25,236 L 18,227 L 11,226 L 11,226 L 11,226\n" +"M 13,214 L 19,217 L 32,227 L 23,214 L 16,208 L 15,190 L 24,148 L 31,121 L 24,137 L 14,170 L 8,189 L 13,214 L 13,214 L 13,214\n" +"M 202,254 L 195,258 L 199,260 L 193,263 L 197,263 L 190,268 L 196,268 L 191,273 L 188,282 L 200,272 L 194,272 L 201,266 L 197,265 L 204,262 L 200,258 L 204,256 L 202,254 L 202,254 L 202,254\n" +"845433\n" +"M 151,213 L 165,212 L 179,225 L 189,246 L 187,262 L 179,275 L 176,263 L 177,247 L 171,233 L 163,230 L 165,251 L 157,264 L 146,298 L 145,321 L 133,326 L 143,285 L 154,260 L 153,240 L 151,213 L 151,213 L 151,213\n" +"M 91,132 L 95,145 L 97,154 L 104,148 L 107,155 L 109,150 L 111,158 L 115,152 L 118,159 L 120,153 L 125,161 L 126,155 L 133,164 L 132,154 L 137,163 L 137,152 L 142,163 L 147,186 L 152,192 L 148,167 L 141,143 L 124,145 L 105,143 L 91,132 L 91,132 L 91,132\n" +"9c826b\n" +"M 31,57 L 23,52 L 26,51 L 20,44 L 23,42 L 21,36 L 22,29 L 25,23 L 24,32 L 30,43 L 26,41 L 30,50 L 26,48 L 31,57 L 31,57 L 31,57\n" +"M 147,21 L 149,28 L 155,21 L 161,16 L 167,14 L 175,15 L 173,11 L 161,9 L 147,21 L 147,21 L 147,21\n" +"M 181,39 L 175,51 L 169,57 L 171,65 L 165,68 L 165,75 L 160,76 L 162,91 L 171,71 L 180,51 L 181,39 L 181,39 L 181,39\n" +"M 132,346 L 139,348 L 141,346 L 142,341 L 147,342 L 143,355 L 133,350 L 132,346 L 132,346 L 132,346\n" +"M 146,355 L 151,352 L 155,348 L 157,343 L 160,349 L 151,356 L 147,357 L 146,355 L 146,355 L 146,355\n" +"M 99,266 L 100,281 L 94,305 L 86,322 L 78,332 L 72,346 L 73,331 L 91,291 L 99,266 L 99,266 L 99,266\n" +"M 20,347 L 32,342 L 45,340 L 54,345 L 45,350 L 42,353 L 38,350 L 31,353 L 29,356 L 23,350 L 19,353 L 15,349 L 20,347 L 20,347 L 20,347\n" +"M 78,344 L 86,344 L 92,349 L 88,358 L 84,352 L 78,344 L 78,344 L 78,344\n" +"M 93,347 L 104,344 L 117,345 L 124,354 L 121,357 L 116,351 L 112,351 L 108,355 L 102,351 L 93,347 L 93,347 L 93,347\n" +"000000\n" +"M 105,12 L 111,18 L 113,24 L 113,29 L 119,34 L 116,23 L 112,16 L 105,12 L 105,12 L 105,12\n" +"M 122,27 L 125,34 L 127,43 L 128,34 L 125,29 L 122,27 L 122,27 L 122,27\n" +"M 115,13 L 122,19 L 122,15 L 113,10 L 115,13 L 115,13 L 115,13\n" +"ffe5b2\n" +"M 116,172 L 107,182 L 98,193 L 98,183 L 90,199 L 89,189 L 84,207 L 88,206 L 87,215 L 95,206 L 93,219 L 91,230 L 98,216 L 97,226 L 104,214 L 112,209 L 104,208 L 113,202 L 126,200 L 139,207 L 132,198 L 142,203 L 134,192 L 142,195 L 134,187 L 140,185 L 130,181 L 136,177 L 126,177 L 125,171 L 116,180 L 116,172 L 116,172 L 116,172\n" +"M 74,220 L 67,230 L 67,221 L 59,235 L 63,233 L 60,248 L 70,232 L 65,249 L 71,243 L 67,256 L 73,250 L 69,262 L 73,259 L 71,267 L 76,262 L 72,271 L 78,270 L 76,275 L 82,274 L 78,290 L 86,279 L 86,289 L 92,274 L 88,275 L 87,264 L 82,270 L 82,258 L 77,257 L 78,247 L 73,246 L 77,233 L 72,236 L 74,220 L 74,220 L 74,220\n" +"M 133,230 L 147,242 L 148,250 L 145,254 L 138,247 L 129,246 L 142,245 L 138,241 L 128,237 L 137,238 L 133,230 L 133,230 L 133,230\n" +"M 133,261 L 125,261 L 116,263 L 111,267 L 125,265 L 133,261 L 133,261 L 133,261\n" +"M 121,271 L 109,273 L 103,279 L 99,305 L 92,316 L 85,327 L 83,335 L 89,340 L 97,341 L 94,336 L 101,336 L 96,331 L 103,330 L 97,327 L 108,325 L 99,322 L 109,321 L 100,318 L 110,317 L 105,314 L 110,312 L 107,310 L 113,308 L 105,306 L 114,303 L 105,301 L 115,298 L 107,295 L 115,294 L 108,293 L 117,291 L 109,289 L 117,286 L 109,286 L 118,283 L 112,281 L 118,279 L 114,278 L 119,276 L 115,274 L 121,271 L 121,271 L 121,271\n" +"M 79,364 L 74,359 L 74,353 L 76,347 L 80,351 L 83,356 L 82,360 L 79,364 L 79,364 L 79,364\n" +"M 91,363 L 93,356 L 97,353 L 103,355 L 105,360 L 103,366 L 99,371 L 94,368 L 91,363 L 91,363 L 91,363\n" +"M 110,355 L 114,353 L 118,357 L 117,363 L 113,369 L 111,362 L 110,355 L 110,355 L 110,355\n" +"M 126,354 L 123,358 L 124,367 L 126,369 L 129,361 L 129,357 L 126,354 L 126,354 L 126,354\n" +"M 30,154 L 24,166 L 20,182 L 23,194 L 29,208 L 37,218 L 41,210 L 41,223 L 46,214 L 46,227 L 52,216 L 52,227 L 61,216 L 59,225 L 68,213 L 73,219 L 70,207 L 77,212 L 69,200 L 77,202 L 70,194 L 78,197 L 68,187 L 76,182 L 64,182 L 58,175 L 58,185 L 53,177 L 50,186 L 46,171 L 44,182 L 39,167 L 36,172 L 36,162 L 30,166 L 30,154 L 30,154 L 30,154\n" +"M 44,130 L 41,137 L 45,136 L 43,150 L 48,142 L 48,157 L 53,150 L 52,164 L 60,156 L 61,169 L 64,165 L 66,175 L 70,167 L 74,176 L 77,168 L 80,183 L 85,172 L 90,182 L 93,174 L 98,181 L 99,173 L 104,175 L 105,169 L 114,168 L 102,163 L 95,157 L 94,166 L 90,154 L 87,162 L 82,149 L 75,159 L 72,148 L 68,155 L 67,143 L 62,148 L 62,138 L 58,145 L 56,133 L 52,142 L 52,128 L 49,134 L 47,125 L 44,130 L 44,130 L 44,130\n" +"M 13,216 L 19,219 L 36,231 L 22,223 L 16,222 L 22,227 L 12,224 L 13,220 L 16,220 L 13,216 L 13,216 L 13,216\n" +"M 10,231 L 14,236 L 25,239 L 27,237 L 19,234 L 10,231 L 10,231 L 10,231\n" +"M 9,245 L 14,242 L 25,245 L 13,245 L 9,245 L 9,245 L 9,245\n" +"M 33,255 L 26,253 L 18,254 L 25,256 L 18,258 L 27,260 L 18,263 L 27,265 L 19,267 L 29,270 L 21,272 L 29,276 L 21,278 L 30,281 L 22,283 L 31,287 L 24,288 L 32,292 L 23,293 L 34,298 L 26,299 L 37,303 L 32,305 L 39,309 L 33,309 L 39,314 L 34,314 L 40,318 L 34,317 L 40,321 L 34,321 L 41,326 L 33,326 L 40,330 L 33,332 L 39,333 L 33,337 L 42,337 L 54,341 L 49,337 L 52,335 L 47,330 L 50,330 L 45,325 L 49,325 L 45,321 L 48,321 L 45,316 L 46,306 L 45,286 L 43,274 L 36,261 L 33,255 L 33,255 L 33,255\n" +"M 7,358 L 9,351 L 14,351 L 17,359 L 11,364 L 7,358 L 7,358 L 7,358\n" +"M 44,354 L 49,351 L 52,355 L 49,361 L 44,354 L 44,354 L 44,354\n" +"M 32,357 L 37,353 L 40,358 L 36,361 L 32,357 L 32,357 L 32,357\n" +"M 139,334 L 145,330 L 154,330 L 158,334 L 154,341 L 152,348 L 145,350 L 149,340 L 147,336 L 141,339 L 139,345 L 136,342 L 136,339 L 139,334 L 139,334 L 139,334\n" +"M 208,259 L 215,259 L 212,255 L 220,259 L 224,263 L 225,274 L 224,283 L 220,292 L 208,300 L 206,308 L 203,304 L 199,315 L 197,309 L 195,318 L 193,313 L 190,322 L 190,316 L 185,325 L 182,318 L 180,325 L 172,321 L 178,320 L 176,313 L 186,312 L 180,307 L 188,307 L 184,303 L 191,302 L 186,299 L 195,294 L 187,290 L 197,288 L 192,286 L 201,283 L 194,280 L 203,277 L 198,275 L 207,271 L 200,269 L 209,265 L 204,265 L 212,262 L 208,259 L 208,259 L 208,259\n" +"M 106,126 L 106,131 L 109,132 L 111,134 L 115,132 L 115,135 L 119,133 L 118,137 L 123,137 L 128,137 L 133,134 L 136,130 L 136,127 L 132,124 L 118,128 L 112,128 L 106,126 L 106,126 L 106,126\n" +"M 107,114 L 101,110 L 98,102 L 105,97 L 111,98 L 119,102 L 121,108 L 118,112 L 113,115 L 107,114 L 107,114 L 107,114\n" +"M 148,106 L 145,110 L 146,116 L 150,118 L 152,111 L 151,107 L 148,106 L 148,106 L 148,106\n" +"M 80,55 L 70,52 L 75,58 L 63,57 L 72,61 L 57,61 L 67,66 L 57,67 L 62,69 L 54,71 L 61,73 L 54,77 L 63,78 L 53,85 L 60,84 L 56,90 L 69,84 L 63,82 L 75,76 L 70,75 L 77,72 L 72,71 L 78,69 L 72,66 L 81,67 L 78,64 L 82,63 L 80,60 L 86,62 L 80,55 L 80,55 L 80,55\n" +"M 87,56 L 91,52 L 96,50 L 102,56 L 98,56 L 92,60 L 87,56 L 87,56 L 87,56\n" +"M 85,68 L 89,73 L 98,76 L 106,74 L 96,73 L 91,70 L 85,68 L 85,68 L 85,68\n" +"M 115,57 L 114,64 L 111,64 L 115,75 L 122,81 L 122,74 L 126,79 L 126,74 L 131,78 L 130,72 L 133,77 L 131,68 L 126,61 L 119,57 L 115,57 L 115,57 L 115,57\n" +"M 145,48 L 143,53 L 147,59 L 151,59 L 150,55 L 145,48 L 145,48 L 145,48\n" +"M 26,22 L 34,15 L 43,10 L 52,10 L 59,16 L 47,15 L 32,22 L 26,22 L 26,22 L 26,22\n" +"M 160,19 L 152,26 L 149,34 L 154,33 L 152,30 L 157,30 L 155,26 L 158,27 L 157,23 L 161,23 L 160,19 L 160,19 L 160,19\n" +"000000\n" +"M 98,117 L 105,122 L 109,122 L 105,117 L 113,120 L 121,120 L 130,112 L 128,108 L 123,103 L 123,99 L 128,101 L 132,106 L 135,109 L 142,105 L 142,101 L 145,101 L 145,91 L 148,101 L 145,105 L 136,112 L 135,116 L 143,124 L 148,120 L 150,122 L 142,128 L 133,122 L 121,125 L 112,126 L 103,125 L 100,129 L 96,124 L 98,117 L 98,117 L 98,117\n" +"M 146,118 L 152,118 L 152,115 L 149,115 L 146,118 L 146,118 L 146,118\n" +"M 148,112 L 154,111 L 154,109 L 149,109 L 148,112 L 148,112 L 148,112\n" +"M 106,112 L 108,115 L 114,116 L 118,114 L 106,112 L 106,112 L 106,112\n" +"M 108,108 L 111,110 L 116,110 L 119,108 L 108,108 L 108,108 L 108,108\n" +"M 106,104 L 109,105 L 117,106 L 115,104 L 106,104 L 106,104 L 106,104\n" +"M 50,25 L 41,26 L 34,33 L 39,43 L 49,58 L 36,51 L 47,68 L 55,69 L 54,59 L 61,57 L 74,46 L 60,52 L 67,42 L 57,48 L 61,40 L 54,45 L 60,36 L 59,29 L 48,38 L 52,30 L 47,32 L 50,25 L 50,25 L 50,25\n" +"M 147,34 L 152,41 L 155,49 L 161,53 L 157,47 L 164,47 L 158,43 L 168,44 L 159,40 L 164,37 L 169,37 L 164,33 L 169,34 L 165,28 L 170,30 L 170,25 L 173,29 L 175,27 L 176,32 L 173,36 L 175,39 L 172,42 L 172,46 L 168,49 L 170,55 L 162,57 L 158,63 L 155,58 L 153,50 L 149,46 L 147,34 L 147,34 L 147,34\n" +"M 155,71 L 159,80 L 157,93 L 157,102 L 155,108 L 150,101 L 149,93 L 154,101 L 152,91 L 151,83 L 155,79 L 155,71 L 155,71 L 155,71\n" +"M 112,78 L 115,81 L 114,91 L 112,87 L 113,82 L 112,78 L 112,78 L 112,78\n" +"M 78,28 L 64,17 L 58,11 L 47,9 L 36,10 L 28,16 L 21,26 L 18,41 L 20,51 L 23,61 L 33,65 L 28,68 L 37,74 L 36,81 L 43,87 L 48,90 L 43,100 L 40,98 L 39,90 L 31,80 L 30,72 L 22,71 L 17,61 L 14,46 L 16,28 L 23,17 L 33,9 L 45,6 L 54,6 L 65,12 L 78,28 L 78,28 L 78,28\n" +"M 67,18 L 76,9 L 87,5 L 101,2 L 118,3 L 135,8 L 149,20 L 149,26 L 144,19 L 132,12 L 121,9 L 105,7 L 89,8 L 76,14 L 70,20 L 67,18 L 67,18 L 67,18\n" +"M 56,98 L 48,106 L 56,103 L 47,112 L 56,110 L 52,115 L 57,113 L 52,121 L 62,115 L 58,123 L 65,119 L 63,125 L 69,121 L 68,127 L 74,125 L 74,129 L 79,128 L 83,132 L 94,135 L 93,129 L 85,127 L 81,122 L 76,126 L 75,121 L 71,124 L 71,117 L 66,121 L 66,117 L 62,117 L 64,112 L 60,113 L 60,110 L 57,111 L 61,105 L 57,107 L 60,101 L 55,102 L 56,98 L 56,98 L 56,98\n" +"M 101,132 L 103,138 L 106,134 L 106,139 L 112,136 L 111,142 L 115,139 L 114,143 L 119,142 L 125,145 L 131,142 L 135,138 L 140,134 L 140,129 L 143,135 L 145,149 L 150,171 L 149,184 L 145,165 L 141,150 L 136,147 L 132,151 L 131,149 L 126,152 L 125,150 L 121,152 L 117,148 L 111,152 L 110,148 L 105,149 L 104,145 L 98,150 L 96,138 L 94,132 L 94,130 L 98,132 L 101,132 L 101,132 L 101,132\n" +"M 41,94 L 32,110 L 23,132 L 12,163 L 6,190 L 7,217 L 5,236 L 3,247 L 9,230 L 12,211 L 12,185 L 18,160 L 26,134 L 35,110 L 43,99 L 41,94 L 41,94 L 41,94\n" +"M 32,246 L 41,250 L 50,257 L 52,267 L 53,295 L 53,323 L 59,350 L 54,363 L 51,365 L 44,366 L 42,360 L 40,372 L 54,372 L 59,366 L 62,353 L 71,352 L 75,335 L 73,330 L 66,318 L 68,302 L 64,294 L 67,288 L 63,286 L 63,279 L 59,275 L 58,267 L 56,262 L 50,247 L 42,235 L 44,246 L 32,236 L 35,244 L 32,246 L 32,246 L 32,246\n" +"M 134,324 L 146,320 L 159,322 L 173,327 L 179,337 L 179,349 L 172,355 L 158,357 L 170,350 L 174,343 L 170,333 L 163,328 L 152,326 L 134,329 L 134,324 L 134,324 L 134,324\n" +"M 173,339 L 183,334 L 184,338 L 191,329 L 194,332 L 199,323 L 202,325 L 206,318 L 209,320 L 213,309 L 221,303 L 228,296 L 232,289 L 234,279 L 233,269 L 230,262 L 225,256 L 219,253 L 208,252 L 198,252 L 210,249 L 223,250 L 232,257 L 237,265 L 238,277 L 238,291 L 232,305 L 221,323 L 218,335 L 212,342 L 200,349 L 178,348 L 173,339 L 173,339 L 173,339\n" +"M 165,296 L 158,301 L 156,310 L 156,323 L 162,324 L 159,318 L 162,308 L 162,304 L 165,296 L 165,296 L 165,296\n" +"M 99,252 L 105,244 L 107,234 L 115,228 L 121,228 L 131,235 L 122,233 L 113,235 L 109,246 L 121,239 L 133,243 L 121,243 L 110,251 L 99,252 L 99,252 L 99,252\n" +"M 117,252 L 124,247 L 134,249 L 136,253 L 126,252 L 117,252 L 117,252 L 117,252\n" +"M 117,218 L 132,224 L 144,233 L 140,225 L 132,219 L 117,218 L 117,218 L 117,218\n" +"M 122,212 L 134,214 L 143,221 L 141,213 L 132,210 L 122,212 L 122,212 L 122,212\n" +"M 69,352 L 70,363 L 76,373 L 86,378 L 97,379 L 108,379 L 120,377 L 128,378 L 132,373 L 135,361 L 133,358 L 132,366 L 127,375 L 121,374 L 121,362 L 119,367 L 117,374 L 110,376 L 110,362 L 107,357 L 106,371 L 104,375 L 97,376 L 90,375 L 90,368 L 86,362 L 83,364 L 86,369 L 85,373 L 78,370 L 73,362 L 71,351 L 69,352 L 69,352 L 69,352\n" +"M 100,360 L 96,363 L 99,369 L 102,364 L 100,360 L 100,360 L 100,360\n" +"M 115,360 L 112,363 L 114,369 L 117,364 L 115,360 L 115,360 L 115,360\n" +"M 127,362 L 125,364 L 126,369 L 128,365 L 127,362 L 127,362 L 127,362\n" +"M 5,255 L 7,276 L 11,304 L 15,320 L 13,334 L 6,348 L 2,353 L 0,363 L 5,372 L 12,374 L 25,372 L 38,372 L 44,369 L 42,367 L 36,368 L 31,369 L 30,360 L 27,368 L 20,370 L 16,361 L 15,368 L 10,369 L 3,366 L 3,359 L 6,352 L 11,348 L 17,331 L 19,316 L 12,291 L 9,274 L 5,255 L 5,255 L 5,255\n" +"M 10,358 L 7,362 L 10,366 L 11,362 L 10,358 L 10,358 L 10,358\n" +"M 25,357 L 22,360 L 24,366 L 27,360 L 25,357 L 25,357 L 25,357\n" +"M 37,357 L 34,361 L 36,365 L 38,361 L 37,357 L 37,357 L 37,357\n" +"M 49,356 L 46,359 L 47,364 L 50,360 L 49,356 L 49,356 L 49,356\n" +"M 130,101 L 132,102 L 135,101 L 139,102 L 143,103 L 142,101 L 137,100 L 133,100 L 130,101 L 130,101 L 130,101\n" +"M 106,48 L 105,52 L 108,56 L 109,52 L 106,48 L 106,48 L 106,48\n" +"M 139,52 L 139,56 L 140,60 L 142,58 L 141,56 L 139,52 L 139,52 L 139,52\n" +"M 25,349 L 29,351 L 30,355 L 33,350 L 37,348 L 42,351 L 45,347 L 49,345 L 44,343 L 36,345 L 25,349 L 25,349 L 25,349\n" +"M 98,347 L 105,351 L 107,354 L 109,349 L 115,349 L 120,353 L 118,349 L 113,346 L 104,346 L 98,347 L 98,347 L 98,347\n" +"M 83,348 L 87,352 L 87,357 L 89,351 L 87,348 L 83,348 L 83,348 L 83,348\n" +"M 155,107 L 163,107 L 170,107 L 186,108 L 175,109 L 155,109 L 155,107 L 155,107 L 155,107\n" +"M 153,114 L 162,113 L 175,112 L 192,114 L 173,114 L 154,115 L 153,114 L 153,114 L 153,114\n" +"M 152,118 L 164,120 L 180,123 L 197,129 L 169,123 L 151,120 L 152,118 L 152,118 L 152,118\n" +"M 68,109 L 87,106 L 107,106 L 106,108 L 88,108 L 68,109 L 68,109 L 68,109\n" +"M 105,111 L 95,112 L 79,114 L 71,116 L 85,115 L 102,113 L 105,111 L 105,111 L 105,111\n" +"M 108,101 L 98,99 L 87,99 L 78,99 L 93,100 L 105,102 L 108,101 L 108,101 L 108,101\n" +"M 85,63 L 91,63 L 97,60 L 104,60 L 108,62 L 111,69 L 112,75 L 110,74 L 108,71 L 103,73 L 106,69 L 105,65 L 103,64 L 103,67 L 102,70 L 99,70 L 97,66 L 94,67 L 97,72 L 88,67 L 84,66 L 85,63 L 85,63 L 85,63\n" +"M 140,74 L 141,66 L 144,61 L 150,61 L 156,62 L 153,70 L 150,73 L 152,65 L 150,65 L 151,68 L 149,71 L 146,71 L 144,66 L 143,70 L 143,74 L 140,74 L 140,74 L 140,74\n" +"M 146,20 L 156,11 L 163,9 L 172,9 L 178,14 L 182,18 L 184,32 L 182,42 L 182,52 L 177,58 L 176,67 L 171,76 L 165,90 L 157,105 L 160,92 L 164,85 L 168,78 L 167,73 L 173,66 L 172,62 L 175,59 L 174,55 L 177,53 L 180,46 L 181,29 L 179,21 L 173,13 L 166,11 L 159,13 L 153,18 L 148,23 L 146,20 L 146,20 L 146,20\n" +"M 150,187 L 148,211 L 150,233 L 153,247 L 148,267 L 135,283 L 125,299 L 136,292 L 131,313 L 122,328 L 122,345 L 129,352 L 133,359 L 133,367 L 137,359 L 148,356 L 140,350 L 131,347 L 129,340 L 132,332 L 140,328 L 137,322 L 140,304 L 154,265 L 157,244 L 155,223 L 161,220 L 175,229 L 186,247 L 185,260 L 176,275 L 178,287 L 185,277 L 188,261 L 196,253 L 189,236 L 174,213 L 150,187 L 150,187 L 150,187\n" +"M 147,338 L 142,341 L 143,345 L 141,354 L 147,343 L 147,338 L 147,338 L 147,338\n" +"M 157,342 L 156,349 L 150,356 L 157,353 L 163,346 L 162,342 L 157,342 L 157,342 L 157,342\n" +"M 99,265 L 96,284 L 92,299 L 73,339 L 73,333 L 87,300 L 99,265 L 99,265 L 99,265\n"; + + + +unsigned parse_lion(agg::path_storage& path, agg::srgba8* colors, unsigned* path_idx) +{ + // Parse the lion and then detect its bounding + // box and arrange polygons orientations (make all polygons + // oriented clockwise or counterclockwise) + + const char* ptr = g_lion; + unsigned npaths = 0; + + while(*ptr) + { + if(*ptr != 'M' && isalnum(*ptr)) + { + unsigned c = 0; + sscanf(ptr, "%x", &c); + + // New color. Every new color creates new path in the path object. + path.close_polygon(); + colors[npaths] = agg::rgb8_packed(c); + path_idx[npaths] = path.start_new_path(); + npaths++; + while(*ptr && *ptr != '\n') ptr++; + if(*ptr == '\n') ptr++; + } + else + { + double x = 0.0; + double y = 0.0; + + while(*ptr && *ptr != '\n') + { + int c = *ptr; + + while(*ptr && !isdigit(*ptr)) ptr++; + x = atof(ptr); + + while(*ptr && isdigit(*ptr)) ptr++; + while(*ptr && !isdigit(*ptr)) ptr++; + y = atof(ptr); + + if(c == 'M') + { + path.close_polygon(); + path.move_to(x, y); + } + else + { + path.line_to(x, y); + } + + while(*ptr && isdigit(*ptr)) ptr++; + while(*ptr && *ptr != '\n' && !isalpha(*ptr)) ptr++; + } + if(*ptr == '\n') ptr++; + } + } + path.arrange_orientations_all_paths(agg::path_flags_cw); + return npaths; +} + diff --git a/examples/pattern_fill.cpp b/examples/pattern_fill.cpp new file mode 100644 index 0000000..7026aaf --- /dev/null +++ b/examples/pattern_fill.cpp @@ -0,0 +1,382 @@ +#include +#include +#include +#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_conv_smooth_poly1.h" +#include "agg_scanline_p.h" +#include "agg_renderer_scanline.h" +#include "agg_span_allocator.h" +#include "agg_span_pattern_gray.h" +#include "agg_span_pattern_rgb.h" +#include "agg_span_pattern_rgba.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" + +enum flip_y_e { flip_y = true }; + +//#define AGG_GRAY8 +//#define AGG_BGR24 +//#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" + + + + +class the_application : public agg::platform_support +{ + agg::slider_ctrl m_polygon_angle; + agg::slider_ctrl m_polygon_scale; + + agg::slider_ctrl m_pattern_angle; + agg::slider_ctrl m_pattern_size; + + agg::slider_ctrl m_pattern_alpha; + + agg::cbox_ctrl m_rotate_polygon; + agg::cbox_ctrl m_rotate_pattern; + agg::cbox_ctrl m_tie_pattern; + + double m_polygon_cx; + double m_polygon_cy; + + double m_dx; + double m_dy; + + int m_flag; + + agg::int8u* m_pattern; + agg::rendering_buffer m_pattern_rbuf; + + agg::rasterizer_scanline_aa<> m_ras; + agg::scanline_p8 m_sl; + agg::path_storage m_ps; + + +public: + //------------------------------------------------------------------------ + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_polygon_angle(5, 5, 145, 12, !flip_y), + m_polygon_scale(5, 5+14, 145, 12+14, !flip_y), + m_pattern_angle(155, 5, 300, 12, !flip_y), + m_pattern_size (155, 5+14, 300, 12+14, !flip_y), + m_pattern_alpha(310, 5, 460, 12, !flip_y), + m_rotate_polygon(5, 5+14+14, "Rotate Polygon", !flip_y), + m_rotate_pattern(5, 5+14+14+14, "Rotate Pattern", !flip_y), + m_tie_pattern (155, 5+14+14, "Tie pattern to polygon", !flip_y), + m_flag(0), + m_pattern(0) + { + add_ctrl(m_polygon_angle); + add_ctrl(m_polygon_scale); + add_ctrl(m_pattern_angle); + add_ctrl(m_pattern_size); + add_ctrl(m_pattern_alpha); + add_ctrl(m_rotate_polygon); + add_ctrl(m_rotate_pattern); + add_ctrl(m_tie_pattern); + + m_polygon_angle.label("Polygon Angle=%3.2f"); + m_polygon_angle.range(-180.0, 180.0); + + m_polygon_scale.label("Polygon Scale=%3.2f"); + m_polygon_scale.range(0.1, 5.0); + m_polygon_scale.value(1.0); + + m_pattern_angle.label("Pattern Angle=%3.2f"); + m_pattern_angle.range(-180.0, 180.0); + + m_pattern_size.label("Pattern Size=%3.2f"); + m_pattern_size.range(10, 40); + m_pattern_size.value(30); + + m_pattern_alpha.label("Background Alpha=%.2f"); + m_pattern_alpha.value(0.1); + } + + //------------------------------------------------------------------------ + virtual ~the_application() + { + delete [] m_pattern; + } + + + //------------------------------------------------------------------------ + void create_star(double xc, double yc, + double r1, double r2, + unsigned n, double start_angle = 0.0) + { + m_ps.remove_all(); + unsigned i; + start_angle *= agg::pi / 180.0; + for(i = 0; i < n; i++) + { + double a = agg::pi * 2.0 * i / n - agg::pi / 2.0; + double dx = cos(a + start_angle); + double dy = sin(a + start_angle); + + if(i & 1) + { + m_ps.line_to(xc + dx * r1, yc + dy * r1); + } + else + { + if(i) m_ps.line_to(xc + dx * r2, yc + dy * r2); + else m_ps.move_to(xc + dx * r2, yc + dy * r2); + } + } + m_ps.close_polygon(); + } + + + //------------------------------------------------------------------------ + void generate_pattern() + { + unsigned size = unsigned(m_pattern_size.value()); + + create_star(m_pattern_size.value() / 2.0, + m_pattern_size.value() / 2.0, + m_pattern_size.value() / 2.5, + m_pattern_size.value() / 6.0, + 6, + m_pattern_angle.value()); + + agg::conv_smooth_poly1_curve smooth(m_ps); + agg::conv_stroke > stroke(smooth); + + smooth.smooth_value(1.0); + smooth.approximation_scale(4.0); + stroke.width(m_pattern_size.value() / 15.0); + + delete [] m_pattern; + m_pattern = new agg::int8u[size * size * pixfmt::pix_width]; + m_pattern_rbuf.attach(m_pattern, size, size, size * pixfmt::pix_width); + + pixfmt pixf(m_pattern_rbuf); + agg::renderer_base rb(pixf); + agg::renderer_scanline_aa_solid > rs(rb); + + rb.clear(agg::rgba_pre(0.4, 0.0, 0.1, m_pattern_alpha.value())); // Pattern background color + + m_ras.add_path(smooth); + rs.color(agg::srgba8(110,130,50)); + agg::render_scanlines(m_ras, m_sl, rs); + + m_ras.add_path(stroke); + rs.color(agg::srgba8(0,50,80)); + agg::render_scanlines(m_ras, m_sl, rs); + } + + + //------------------------------------------------------------------------ + virtual void on_init() + { + m_polygon_cx = initial_width() / 2.0; + m_polygon_cy = initial_height() / 2.0; + generate_pattern(); + } + + + //------------------------------------------------------------------------ + virtual void on_draw() + { + double width = rbuf_window().width(); + double height = rbuf_window().height(); + + typedef agg::renderer_base renderer_base; + typedef agg::renderer_base 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 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); + + double r = initial_width() / 3.0 - 8.0; + create_star(m_polygon_cx, m_polygon_cy, r, r / 1.45, 14); + + agg::conv_transform tr(m_ps, polygon_mtx); + + typedef agg::wrap_mode_reflect_auto_pow2 wrap_x_type; + typedef agg::wrap_mode_reflect_auto_pow2 wrap_y_type; + typedef agg::image_accessor_wrap img_source_type; + typedef agg::span_pattern_rgba span_gen_type; + + unsigned offset_x = 0; + unsigned offset_y = 0; + + if(m_tie_pattern.status()) + { + offset_x = unsigned(width-m_polygon_cx); + offset_y = unsigned(height-m_polygon_cy); + } + + agg::span_allocator sa; + pixfmt img_pixf(m_pattern_rbuf); + img_source_type img_src(img_pixf); + span_gen_type sg(img_src, offset_x, offset_y); + + // Alpha is meaningful for RGB only because RGBA has its own + sg.alpha(span_gen_type::value_type(m_pattern_alpha.value() * 255.0)); + + m_ras.add_path(tr); + agg::render_scanlines_aa(m_ras, m_sl, rb_pre, sa, sg); + + agg::render_ctrl(m_ras, m_sl, rb, m_polygon_angle); + agg::render_ctrl(m_ras, m_sl, rb, m_polygon_scale); + agg::render_ctrl(m_ras, m_sl, rb, m_pattern_angle); + agg::render_ctrl(m_ras, m_sl, rb, m_pattern_size); + agg::render_ctrl(m_ras, m_sl, rb, m_pattern_alpha); + agg::render_ctrl(m_ras, m_sl, rb, m_rotate_polygon); + agg::render_ctrl(m_ras, m_sl, rb, m_rotate_pattern); + agg::render_ctrl(m_ras, m_sl, rb, m_tie_pattern); + } + + + + //------------------------------------------------------------------------ + virtual void on_mouse_button_down(int x, int y, unsigned flags) + { + if(flags & agg::mouse_left) + { + 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); + + double r = initial_width() / 3.0 - 8.0; + create_star(m_polygon_cx, m_polygon_cy, r, r / 1.45, 14); + + agg::conv_transform tr(m_ps, polygon_mtx); + m_ras.add_path(tr); + if(m_ras.hit_test(x, y)) + { + m_dx = x - m_polygon_cx; + m_dy = y - m_polygon_cy; + m_flag = 1; + } + } + } + + + //------------------------------------------------------------------------ + virtual void on_mouse_move(int x, int y, unsigned flags) + { + if(flags & agg::mouse_left) + { + if(m_flag) + { + 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_pattern.status()) + { + wait_mode(false); + } + else + { + wait_mode(true); + } + + generate_pattern(); + 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_pattern.status()) + { + m_pattern_angle.value(m_pattern_angle.value() - 0.5); + if(m_pattern_angle.value() <= -180.0) + { + m_pattern_angle.value(m_pattern_angle.value() + 360.0); + } + generate_pattern(); + redraw = true; + } + + if(redraw) force_redraw(); + + } + + +}; + + + + + +int agg_main(int argc, char* argv[]) +{ + the_application app(pix_format, flip_y); + app.caption("AGG Example: Pattern Filling"); + + if(app.init(640, 480, 0)) + { + return app.run(); + } + return 0; +} + + diff --git a/examples/pattern_perspective.cpp b/examples/pattern_perspective.cpp new file mode 100644 index 0000000..ba67759 --- /dev/null +++ b/examples/pattern_perspective.cpp @@ -0,0 +1,297 @@ +#include +#include +#include +#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_interpolator_linear.h" +#include "agg_span_interpolator_trans.h" +#include "agg_span_allocator.h" +#include "agg_image_accessors.h" +#include "ctrl/agg_rbox_ctrl.h" +#include "platform/agg_platform_support.h" +#include "interactive_polygon.h" + +#define AGG_BGR24 +#include "pixel_formats.h" + +#include "agg_span_image_filter_rgb.h" +#define span_image_filter_2x2 agg::span_image_filter_rgb_2x2 +#define span_image_filter_nn agg::span_image_filter_rgb_nn + +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 renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_solid; + typedef agg::renderer_base renderer_base_pre; + + agg::interactive_polygon m_quad; + agg::rbox_ctrl m_trans_type; + bool m_test_flag; + + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_quad(4, 5.0), + m_trans_type(460, 5.0, 420+170.0, 60.0, !flip_y), + m_test_flag(false) + { + m_trans_type.text_size(8); + m_trans_type.text_thickness(1); + m_trans_type.add_item("Affine"); + 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() + { + g_x1 = -150; + g_y1 = -150; + g_x2 = 150; + g_y2 = 150; + + double trans_x1 = -200; + double trans_y1 = -200; + double trans_x2 = 200; + double trans_y2 = 200; + + double dx = width() / 2.0 - (trans_x2 + trans_x1) / 2.0; + double dy = height() / 2.0 - (trans_y2 + trans_y1) / 2.0; + m_quad.xn(0) = floor(trans_x1 + dx); + m_quad.yn(0) = floor(trans_y1 + dy); + m_quad.xn(1) = floor(trans_x2 + dx); + m_quad.yn(1) = floor(trans_y1 + dy); + m_quad.xn(2) = floor(trans_x2 + dx); + m_quad.yn(2) = floor(trans_y2 + dy); + m_quad.xn(3) = floor(trans_x1 + dx); + m_quad.yn(3) = floor(trans_y2 + dy); + } + + 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); + + if(!m_test_flag) + { + 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)); + } + + if(!m_test_flag) + { + //-------------------------- + // 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)); + + //-------------------------- + agg::render_ctrl(g_rasterizer, g_scanline, rb, m_trans_type); + } + + // 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)); + + + typedef agg::span_allocator span_alloc_type; + span_alloc_type sa; + agg::image_filter filter; + + typedef agg::wrap_mode_reflect_auto_pow2 remainder_type; + typedef agg::image_accessor_wrap img_source_type; + + pixfmt img_pixf(rbuf_img(0)); + img_source_type img_src(img_pixf); + + enum subdiv_shift_e { subdiv_shift = 2 }; + + 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 interpolator_type; + interpolator_type interpolator(tr); + + typedef span_image_filter_2x2 span_gen_type; + span_gen_type sg(img_src, interpolator, filter); + 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 interpolator_type; + interpolator_type interpolator(tr); + + typedef span_image_filter_2x2 span_gen_type; + span_gen_type sg(img_src, 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()) + { + typedef agg::span_interpolator_linear_subdiv interpolator_type; + interpolator_type interpolator(tr); + + typedef span_image_filter_2x2 span_gen_type; + span_gen_type sg(img_src, interpolator, filter); + agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg); + } + break; + } + } + } + + + + 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(); + } + else + { + start_timer(); + m_test_flag = true; + on_draw(); + on_draw(); + on_draw(); + on_draw(); + char buf[100]; + sprintf(buf, "time=%.3f", elapsed_time()); + m_test_flag = false; + force_redraw(); + message(buf); + } + + } + } + + + 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. Pattern Perspective Transformations"); + + const char* img_name = "agg"; + if(argc >= 2) img_name = argv[1]; + if(!app.load_img(0, img_name)) + { + char buf[256]; + if(strcmp(img_name, "agg") == 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; +} + + + + + + diff --git a/examples/pattern_resample.cpp b/examples/pattern_resample.cpp new file mode 100644 index 0000000..f271367 --- /dev/null +++ b/examples/pattern_resample.cpp @@ -0,0 +1,399 @@ +#include +#include +#include +#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" + + +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_pixfmt_rgb.h" +#include "agg_span_image_filter_rgb.h" +#define pix_format agg::pix_format_bgr24 +typedef agg::pixfmt_bgr24 pixfmt; +typedef agg::pixfmt_bgr24_pre pixfmt_pre; +#define span_image_filter_2x2 agg::span_image_filter_rgb_2x2 +#define span_image_resample_affine agg::span_image_resample_rgb_affine +#define span_image_resample agg::span_image_resample_rgb + +typedef pixfmt::color_type color_type; +typedef color_type::value_type value_type; +typedef agg::renderer_base renderer_base; +typedef agg::renderer_base renderer_base_pre; +typedef agg::renderer_scanline_aa_solid renderer_solid; +enum base_scale_e { base_shift = color_type::base_shift }; + +class the_application : public agg::platform_support +{ +public: + agg::gamma_lut m_gamma_lut; + agg::interactive_polygon m_quad; + agg::rbox_ctrl m_trans_type; + agg::slider_ctrl m_gamma; + agg::slider_ctrl m_blur; + double m_old_gamma; + + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_gamma_lut(2.0), + m_quad(4, 5.0), + m_trans_type(400, 5.0, 430+170.0, 100.0, !flip_y), + m_gamma(5.0, 5.0+15*0, 400-5, 10.0+15*0, !flip_y), + m_blur (5.0, 5.0+15*1, 400-5, 10.0+15*1, !flip_y), + m_old_gamma(2.0) + { + 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_gamma.range(0.5, 3.0); + m_gamma.value(2.0); + m_gamma.label("Gamma=%.3f"); + add_ctrl(m_gamma); + + m_blur.range(0.5, 2.0); + m_blur.value(1.0); + m_blur.label("Blur=%.3f"); + add_ctrl(m_blur); + } + + + virtual void on_init() + { + g_x1 = -150; + g_y1 = -150; + g_x2 = 150; + g_y2 = 150; + + double trans_x1 = -200; + double trans_y1 = -200; + double trans_x2 = 200; + double trans_y2 = 200; + + double dx = width() / 2.0 - (trans_x2 + trans_x1) / 2.0; + double dy = height() / 2.0 - (trans_y2 + trans_y1) / 2.0; + m_quad.xn(0) = floor(trans_x1 + dx); + m_quad.yn(0) = floor(trans_y1 + dy); + m_quad.xn(1) = floor(trans_x2 + dx); + m_quad.yn(1) = floor(trans_y1 + dy); + m_quad.xn(2) = floor(trans_x2 + dx); + m_quad.yn(2) = floor(trans_y2 + dy); + m_quad.xn(3) = floor(trans_x1 + dx); + m_quad.yn(3) = floor(trans_y2 + dy); + + pixfmt pixf(rbuf_img(0)); + pixf.apply_gamma_dir(m_gamma_lut); + } + + virtual void on_draw() + { + if(m_gamma.value() != m_old_gamma) + { + m_gamma_lut.gamma(m_gamma.value()); + load_img(0, "agg"); + pixfmt pixf(rbuf_img(0)); + pixf.apply_gamma_dir(m_gamma_lut); + m_old_gamma = m_gamma.value(); + } + + 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.1)); + 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 span_alloc_type; + span_alloc_type sa; + agg::image_filter_hanning filter_kernel; + agg::image_filter_lut filter(filter_kernel, true); + + typedef agg::wrap_mode_reflect_auto_pow2 wrap_type; + typedef agg::image_accessor_wrap img_source_type; + + pixfmt img_pixf(rbuf_img(0)); + img_source_type img_src(img_pixf); + + 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 interpolator_type; + interpolator_type interpolator(tr); + + typedef span_image_filter_2x2 span_gen_type; + span_gen_type sg(img_src, 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 interpolator_type; + typedef span_image_resample_affine span_gen_type; + interpolator_type interpolator(tr); + span_gen_type sg(img_src, 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 interpolator_type; + interpolator_type interpolator(tr); + + typedef span_image_filter_2x2 span_gen_type; + span_gen_type sg(img_src, 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 interpolator_type; + interpolator_type interpolator(tr); + + typedef span_image_filter_2x2 span_gen_type; + span_gen_type sg(img_src, 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 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 span_image_resample span_gen_type; + span_gen_type sg(img_src, 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 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 span_image_resample span_gen_type; + span_gen_type sg(img_src, 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(); + pixf.apply_gamma_inv(m_gamma_lut); + + char buf[64]; + agg::gsv_text t; + t.size(10.0); + + agg::conv_stroke 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_gamma); + 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. Pattern Transformations with Resampling"); + + const char* img_name = "agg"; + if(argc >= 2) img_name = argv[1]; + if(!app.load_img(0, img_name)) + { + char buf[256]; + if(strcmp(img_name, "agg") == 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; +} + + + + + + diff --git a/examples/perspective.cpp b/examples/perspective.cpp new file mode 100644 index 0000000..c62740e --- /dev/null +++ b/examples/perspective.cpp @@ -0,0 +1,311 @@ +#include +#include +#include +#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_conv_clip_polygon.h" +#include "agg_bounding_rect.h" +#include "agg_ellipse.h" +#include "agg_trans_bilinear.h" +#include "agg_trans_perspective.h" +#include "ctrl/agg_rbox_ctrl.h" +#include "platform/agg_platform_support.h" +#include "interactive_polygon.h" + +#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 }; + +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 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; + g_path.flip_x(g_x1, g_x2); + g_path.flip_y(g_y1, g_y2); +} + + + + +namespace agg +{ +} + + + + + + + +class the_application : public agg::platform_support +{ +public: + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_solid; + + agg::interactive_polygon m_quad; + agg::rbox_ctrl 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+130.0, 55.0, !flip_y) + { + parse_lion(); + m_quad.xn(0) = g_x1; + m_quad.yn(0) = g_y1; + m_quad.xn(1) = g_x2; + m_quad.yn(1) = g_y1; + m_quad.xn(2) = g_x2; + m_quad.yn(2) = g_y2; + m_quad.xn(3) = g_x1; + m_quad.yn(3) = g_y2; + + m_trans_type.add_item("Bilinear"); + m_trans_type.add_item("Perspective"); + m_trans_type.cur_item(0); + add_ctrl(m_trans_type); + } + + + virtual void on_init() + { + double dx = width() / 2.0 - (m_quad.xn(1) - m_quad.xn(0)) / 2.0; + double dy = height() / 2.0 - (m_quad.yn(2) - m_quad.yn(0)) / 2.0; + m_quad.xn(0) += dx; + m_quad.yn(0) += dy; + m_quad.xn(1) += dx; + m_quad.yn(1) += dy; + m_quad.xn(2) += dx; + m_quad.yn(2) += dy; + m_quad.xn(3) += dx; + m_quad.yn(3) += dy; + } + + virtual void on_draw() + { + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_solid r(rb); + rb.clear(agg::rgba(1, 1, 1)); + + g_rasterizer.clip_box(0, 0, width(), height()); + + if(m_trans_type.cur_item() == 0) + { + agg::trans_bilinear tr(g_x1, g_y1, g_x2, g_y2, m_quad.polygon()); + if(tr.is_valid()) + { + //-------------------------- + // Render transformed lion + // + agg::conv_transform trans(g_path, tr); + + agg::render_all_paths(g_rasterizer, g_scanline, r, trans, g_colors, g_path_idx, g_npaths); + //-------------------------- + + + + //-------------------------- + // Render transformed ellipse + // + agg::ellipse ell((g_x1 + g_x2) * 0.5, (g_y1 + g_y2) * 0.5, + (g_x2 - g_x1) * 0.5, (g_y2 - g_y1) * 0.5, + 200); + agg::conv_stroke ell_stroke(ell); + ell_stroke.width(3.0); + agg::conv_transform trans_ell(ell, tr); + + agg::conv_transform, + agg::trans_bilinear> trans_ell_stroke(ell_stroke, tr); + + g_rasterizer.add_path(trans_ell); + r.color(agg::rgba(0.5, 0.3, 0.0, 0.3)); + agg::render_scanlines(g_rasterizer, g_scanline, r); + + g_rasterizer.add_path(trans_ell_stroke); + r.color(agg::rgba(0.0, 0.3, 0.2, 1.0)); + agg::render_scanlines(g_rasterizer, g_scanline, r); + //-------------------------- + + } + } + else + { + agg::trans_perspective tr(g_x1, g_y1, g_x2, g_y2, m_quad.polygon()); + if(tr.is_valid()) + { + + //-------------------------- + // Render transformed lion + // + agg::conv_transform trans(g_path, tr); + + agg::render_all_paths(g_rasterizer, g_scanline, r, trans, g_colors, g_path_idx, g_npaths); + + //-------------------------- + + + + //-------------------------- + // Render transformed ellipse + // + agg::ellipse ell((g_x1 + g_x2) * 0.5, (g_y1 + g_y2) * 0.5, + (g_x2 - g_x1) * 0.5, (g_y2 - g_y1) * 0.5, + 200); + + agg::conv_stroke ell_stroke(ell); + ell_stroke.width(3.0); + agg::conv_transform trans_ell(ell, tr); + + + agg::conv_transform, + agg::trans_perspective> trans_ell_stroke(ell_stroke, tr); + + + g_rasterizer.add_path(trans_ell); + r.color(agg::rgba(0.5, 0.3, 0.0, 0.3)); + agg::render_scanlines(g_rasterizer, g_scanline, r); + + g_rasterizer.add_path(trans_ell_stroke); + r.color(agg::rgba(0.0, 0.3, 0.2, 1.0)); + agg::render_scanlines(g_rasterizer, g_scanline, r); + //-------------------------- + + + // Testing the reverse transformations + //agg::trans_perspective tr2(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2); + //if(tr2.is_valid()) + //{ + // double x, y; + // x = m_quad.xn(0); y = m_quad.yn(0); tr2.transform(&x, &y); + // g_rasterizer.move_to_d(x, y); + // x = m_quad.xn(1); y = m_quad.yn(1); tr2.transform(&x, &y); + // g_rasterizer.line_to_d(x, y); + // x = m_quad.xn(2); y = m_quad.yn(2); tr2.transform(&x, &y); + // g_rasterizer.line_to_d(x, y); + // x = m_quad.xn(3); y = m_quad.yn(3); tr2.transform(&x, &y); + // g_rasterizer.line_to_d(x, y); + // r.color(agg::rgba(0.5, 0.0, 0.0, 0.5)); + // agg::render_scanlines(g_rasterizer, g_scanline, r); + //} + //else + //{ + // message("Singularity..."); + //} + } + } + + + + + //-------------------------- + // Render the "quad" tool and controls + g_rasterizer.add_path(m_quad); + r.color(agg::rgba(0, 0.3, 0.5, 0.6)); + agg::render_scanlines(g_rasterizer, g_scanline, r); + 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. Perspective Transformations"); + + if(app.init(600, 600, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + + + + + diff --git a/examples/pixel_formats.h b/examples/pixel_formats.h new file mode 100644 index 0000000..34ca2b2 --- /dev/null +++ b/examples/pixel_formats.h @@ -0,0 +1,344 @@ +#ifndef PIXEL_FORMATS_INCLUDED +#define PIXEL_FORMATS_INCLUDED + +#if defined(AGG_GRAY8) + +#include "agg_pixfmt_gray.h" +const agg::pix_format_e pix_format = agg::pix_format_gray8; +typedef agg::pixfmt_gray8 pixfmt; +typedef agg::pixfmt_gray8_pre pixfmt_pre; +typedef agg::gray8 color_type; +typedef agg::gray8 gray_type; + +#elif defined(AGG_SGRAY8) + +#include "agg_pixfmt_gray.h" +const agg::pix_format_e pix_format = agg::pix_format_sgray8; +typedef agg::pixfmt_sgray8 pixfmt; +typedef agg::pixfmt_sgray8_pre pixfmt_pre; +typedef agg::sgray8 color_type; +typedef agg::sgray8 gray_type; + +#elif defined(AGG_GRAY16) + +#include "agg_pixfmt_gray.h" +const agg::pix_format_e pix_format = agg::pix_format_gray16; +typedef agg::pixfmt_gray16 pixfmt; +typedef agg::pixfmt_gray16_pre pixfmt_pre; +typedef agg::gray16 color_type; +typedef agg::gray16 gray_type; + +#elif defined(AGG_GRAY32) + +#include "agg_pixfmt_gray.h" +const agg::pix_format_e pix_format = agg::pix_format_gray32; +typedef agg::pixfmt_gray32 pixfmt; +typedef agg::pixfmt_gray32_pre pixfmt_pre; +typedef agg::gray32 color_type; +typedef agg::gray32 gray_type; + +#elif defined(AGG_BGR24) + +#include "agg_pixfmt_rgb.h" +const agg::pix_format_e pix_format = agg::pix_format_bgr24; +typedef agg::pixfmt_bgr24 pixfmt; +typedef agg::pixfmt_bgr24_pre pixfmt_pre; +#define pixfmt_gamma agg::pixfmt_bgr24_gamma +typedef agg::rgba8 color_type; +typedef agg::order_bgr component_order; +typedef agg::gray8 gray_type; + +#elif defined(AGG_RGB24) + +#include "agg_pixfmt_rgb.h" +const agg::pix_format_e pix_format = agg::pix_format_rgb24; +typedef agg::pixfmt_rgb24 pixfmt; +typedef agg::pixfmt_rgb24_pre pixfmt_pre; +#define pixfmt_gamma agg::pixfmt_rgb24_gamma +typedef agg::rgba8 color_type; +typedef agg::order_rgb component_order; +typedef agg::gray8 gray_type; + +#elif defined(AGG_SBGR24) + +#include "agg_pixfmt_rgb.h" +const agg::pix_format_e pix_format = agg::pix_format_sbgr24; +typedef agg::pixfmt_sbgr24 pixfmt; +typedef agg::pixfmt_sbgr24_pre pixfmt_pre; +#define pixfmt_gamma agg::pixfmt_sbgr24_gamma +typedef agg::srgba8 color_type; +typedef agg::order_bgr component_order; +typedef agg::sgray8 gray_type; + +#elif defined(AGG_SRGB24) + +#include "agg_pixfmt_rgb.h" +const agg::pix_format_e pix_format = agg::pix_format_srgb24; +typedef agg::pixfmt_srgb24 pixfmt; +typedef agg::pixfmt_srgb24_pre pixfmt_pre; +#define pixfmt_gamma agg::pixfmt_srgb24_gamma +typedef agg::srgba8 color_type; +typedef agg::order_rgb component_order; +typedef agg::sgray8 gray_type; + +#elif defined(AGG_BGR48) + +#include "agg_pixfmt_rgb.h" +const agg::pix_format_e pix_format = agg::pix_format_bgr48; +typedef agg::pixfmt_bgr48 pixfmt; +typedef agg::pixfmt_bgr48_pre pixfmt_pre; +#define pixfmt_gamma agg::pixfmt_bgr48_gamma +typedef agg::rgba16 color_type; +typedef agg::order_bgr component_order; +typedef agg::gray16 gray_type; + +#elif defined(AGG_RGB48) + +#include "agg_pixfmt_rgb.h" +const agg::pix_format_e pix_format = agg::pix_format_rgb48; +typedef agg::pixfmt_rgb48 pixfmt; +typedef agg::pixfmt_rgb48_pre pixfmt_pre; +#define pixfmt_gamma agg::pixfmt_rgb48_gamma +typedef agg::rgba16 color_type; +typedef agg::order_rgb component_order; +typedef agg::gray16 gray_type; + +#elif defined(AGG_BGR96) + +#include "agg_pixfmt_rgb.h" +const agg::pix_format_e pix_format = agg::pix_format_bgr96; +typedef agg::pixfmt_bgr96 pixfmt; +typedef agg::pixfmt_bgr96_pre pixfmt_pre; +typedef agg::rgba32 color_type; +typedef agg::order_bgr component_order; +typedef agg::gray32 gray_type; + +#elif defined(AGG_RGB96) + +#include "agg_pixfmt_rgb.h" +const agg::pix_format_e pix_format = agg::pix_format_rgb96; +typedef agg::pixfmt_rgb96 pixfmt; +typedef agg::pixfmt_rgb96_pre pixfmt_pre; +typedef agg::rgba32 color_type; +typedef agg::order_bgr component_order; +typedef agg::gray32 gray_type; + +#elif defined(AGG_BGRA32) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_bgra32; +typedef agg::pixfmt_bgra32 pixfmt; +typedef agg::pixfmt_bgra32_pre pixfmt_pre; +typedef agg::rgba8 color_type; +typedef agg::order_bgra component_order; +typedef agg::gray8 gray_type; + +#elif defined(AGG_RGBA32) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_rgba32; +typedef agg::pixfmt_rgba32 pixfmt; +typedef agg::pixfmt_rgba32_pre pixfmt_pre; +typedef agg::rgba8 color_type; +typedef agg::order_rgba component_order; +typedef agg::gray8 gray_type; + +#elif defined(AGG_ARGB32) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_argb32; +typedef agg::pixfmt_argb32 pixfmt; +typedef agg::pixfmt_argb32_pre pixfmt_pre; +typedef agg::rgba8 color_type; +typedef agg::order_argb component_order; +typedef agg::gray8 gray_type; + +#elif defined(AGG_ABGR32) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_abgr32; +typedef agg::pixfmt_abgr32 pixfmt; +typedef agg::pixfmt_abgr32_pre pixfmt_pre; +typedef agg::rgba8 color_type; +typedef agg::order_argb component_order; +typedef agg::gray8 gray_type; + +#elif defined(AGG_SBGRA32) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_sbgra32; +typedef agg::pixfmt_sbgra32 pixfmt; +typedef agg::pixfmt_sbgra32_pre pixfmt_pre; +typedef agg::srgba8 color_type; +typedef agg::order_bgra component_order; +typedef agg::sgray8 gray_type; + +#elif defined(AGG_SRGBA32) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_srgba32; +typedef agg::pixfmt_srgba32 pixfmt; +typedef agg::pixfmt_srgba32_pre pixfmt_pre; +typedef agg::srgba8 color_type; +typedef agg::order_rgba component_order; +typedef agg::sgray8 gray_type; + +#elif defined(AGG_SARGB32) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_sargb32; +typedef agg::pixfmt_sargb32 pixfmt; +typedef agg::pixfmt_sargb32_pre pixfmt_pre; +typedef agg::srgba8 color_type; +typedef agg::order_argb component_order; +typedef agg::sgray8 gray_type; + +#elif defined(AGG_SABGR32) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_sabgr32; +typedef agg::pixfmt_sabgr32 pixfmt; +typedef agg::pixfmt_sabgr32_pre pixfmt_pre; +typedef agg::srgba8 color_type; +typedef agg::order_argb component_order; +typedef agg::sgray8 gray_type; + +#elif defined(AGG_BGRA64) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_bgra64; +typedef agg::pixfmt_bgra64 pixfmt; +typedef agg::pixfmt_bgra64_pre pixfmt_pre; +typedef agg::rgba16 color_type; +typedef agg::order_bgra component_order; +typedef agg::gray16 gray_type; + +#elif defined(AGG_RGBA64) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_rgba64; +typedef agg::pixfmt_rgba64 pixfmt; +typedef agg::pixfmt_rgba64_pre pixfmt_pre; +typedef agg::rgba16 color_type; +typedef agg::order_rgba component_order; +typedef agg::gray16 gray_type; + +#elif defined(AGG_ARGB64) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_argb64; +typedef agg::pixfmt_argb64 pixfmt; +typedef agg::pixfmt_argb64_pre pixfmt_pre; +typedef agg::rgba16 color_type; +typedef agg::order_argb component_order; +typedef agg::gray16 gray_type; + +#elif defined(AGG_ABGR64) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_abgr64; +typedef agg::pixfmt_abgr64 pixfmt; +typedef agg::pixfmt_abgr64_pre pixfmt_pre; +typedef agg::rgba16 color_type; +typedef agg::order_argb component_order; +typedef agg::gray16 gray_type; + +#elif defined(AGG_BGRA128) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_bgra128; +typedef agg::pixfmt_bgra128 pixfmt; +typedef agg::pixfmt_bgra128_pre pixfmt_pre; +typedef agg::rgba32 color_type; +typedef agg::order_bgra component_order; +typedef agg::gray32 gray_type; + +#elif defined(AGG_RGBA128) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_rgba128; +typedef agg::pixfmt_rgba128 pixfmt; +typedef agg::pixfmt_rgba128_pre pixfmt_pre; +typedef agg::rgba32 color_type; +typedef agg::order_rgba component_order; +typedef agg::gray32 gray_type; + +#elif defined(AGG_ARGB128) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_argb128; +typedef agg::pixfmt_argb128 pixfmt; +typedef agg::pixfmt_argb128_pre pixfmt_pre; +typedef agg::rgba32 color_type; +typedef agg::order_argb component_order; +typedef agg::gray32 gray_type; + +#elif defined(AGG_ABGR128) + +#include "agg_pixfmt_rgba.h" +const agg::pix_format_e pix_format = agg::pix_format_abgr128; +typedef agg::pixfmt_abgr128 pixfmt; +typedef agg::pixfmt_abgr128_pre pixfmt_pre; +typedef agg::rgba32 color_type; +typedef agg::order_argb component_order; +typedef agg::gray32 gray_type; + +#elif defined(AGG_RGB565) + +#include "agg_pixfmt_rgb_packed.h" +const agg::pix_format_e pix_format = agg::pix_format_rgb565; +typedef agg::pixfmt_rgb565 pixfmt; +typedef agg::pixfmt_rgb565_pre pixfmt_pre; +typedef agg::rgba8 color_type; +typedef agg::gray8 gray_type; + +#elif defined(AGG_RGB555) + +#include "agg_pixfmt_rgb_packed.h" +const agg::pix_format_e pix_format = agg::pix_format_rgb555; +typedef agg::pixfmt_rgb555 pixfmt; +typedef agg::pixfmt_rgb555_pre pixfmt_pre; +typedef agg::rgba8 color_type; +typedef agg::gray8 gray_type; + +#elif defined(AGG_RGB_AAA) + +#include "agg_pixfmt_rgb_packed.h" +const agg::pix_format_e pix_format = agg::pix_format_rgbAAA; +typedef agg::pixfmt_rgbAAA pixfmt; +typedef agg::pixfmt_rgbAAA_pre pixfmt_pre; +typedef agg::rgba16 color_type; +typedef agg::gray16 gray_type; + +#elif defined(AGG_BGR_AAA) + +#include "agg_pixfmt_rgb_packed.h" +const agg::pix_format_e pix_format = agg::pix_format_bgrAAA; +typedef agg::pixfmt_bgrAAA pixfmt; +typedef agg::pixfmt_bgrAAA_pre pixfmt_pre; +typedef agg::rgba16 color_type; +typedef agg::gray16 gray_type; + +#elif defined(AGG_RGB_BBA) + +#include "agg_pixfmt_rgb_packed.h" +const agg::pix_format_e pix_format = agg::pix_format_rgbBBA; +typedef agg::pixfmt_rgbBBA pixfmt; +typedef agg::pixfmt_rgbBBA_pre pixfmt_pre; +typedef agg::rgba16 color_type; +typedef agg::gray16 gray_type; + +#elif defined(AGG_BGR_ABB) + +#include "agg_pixfmt_rgb_packed.h" +const agg::pix_format_e pix_format = agg::pix_format_bgrABB; +typedef agg::pixfmt_bgrABB pixfmt; +typedef agg::pixfmt_bgrABB_pre pixfmt_pre; +typedef agg::rgba16 color_type; +typedef agg::gray16 gray_type; + +#else +#error Please define pixel format: AGG_GRAY8, AGG_BGR24, AGG_RGB24, etc. See this file above +#endif + +#endif diff --git a/examples/polymorphic_renderer.cpp b/examples/polymorphic_renderer.cpp new file mode 100644 index 0000000..f751890 --- /dev/null +++ b/examples/polymorphic_renderer.cpp @@ -0,0 +1,167 @@ +#include +#include +#include +#include "agg_basics.h" +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_rasterizer_outline.h" +#include "agg_scanline_p.h" +#include "agg_path_storage.h" +#include "agg_renderer_scanline.h" +#include "platform/agg_platform_support.h" + +#include "agg_pixfmt_rgb.h" +#include "agg_pixfmt_rgb_packed.h" +#include "agg_pixfmt_rgba.h" + +static int pix_fmt = agg::pix_format_rgb555; +//static int pix_fmt = agg::pix_format_rgb565; +//static int pix_fmt = agg::pix_format_rgb24; +//static int pix_fmt = agg::pix_format_bgr24; +//static int pix_fmt = agg::pix_format_rgba32; +//static int pix_fmt = agg::pix_format_argb32; +//static int pix_fmt = agg::pix_format_abgr32; +//static int pix_fmt = agg::pix_format_bgra32; + + +enum flip_y_e { flip_y = true }; + +namespace agg +{ + //======================================================================== + class polymorphic_renderer_solid_rgba8_base + { + public: + typedef srgba8 color_type; + typedef scanline_p8 scanline_type; + + virtual ~polymorphic_renderer_solid_rgba8_base() {} + + //-------------------------------------------------------------------- + virtual void clear(const color_type& c) = 0; + virtual void color(const color_type& c) = 0; + virtual const color_type color() const = 0; + virtual void prepare() = 0; + virtual void render(const scanline_type&) = 0; + }; + + + + //======================================================================== + template class polymorphic_renderer_solid_rgba8_adaptor : + public polymorphic_renderer_solid_rgba8_base + { + public: + polymorphic_renderer_solid_rgba8_adaptor(rendering_buffer& rbuf) : + m_pixfmt(rbuf), + m_ren_base(m_pixfmt), + m_ren(m_ren_base) + {} + + //-------------------------------------------------------------------- + virtual void clear(const color_type& c) + { + m_ren_base.clear(c); + } + + virtual void color(const color_type& c) + { + m_ren.color(c); + } + + virtual const color_type color() const + { + return m_ren.color(); + } + + virtual void prepare() + { + m_ren.prepare(); + } + + virtual void render(const scanline_type& sl) + { + m_ren.render(sl); + } + + private: + PixFmt m_pixfmt; + renderer_base m_ren_base; + renderer_scanline_aa_solid > m_ren; + }; + + +} + + + + + + + +class the_application : public agg::platform_support +{ + double m_x[3]; + double m_y[3]; + +public: + the_application(int format, bool flip_y) : + agg::platform_support((agg::pix_format_e)format, flip_y) + { + m_x[0] = 100; m_y[0] = 60; + m_x[1] = 369; m_y[1] = 170; + m_x[2] = 143; m_y[2] = 310; + } + + virtual void on_draw() + { + agg::path_storage path; + path.move_to(m_x[0], m_y[0]); + path.line_to(m_x[1], m_y[1]); + path.line_to(m_x[2], m_y[2]); + path.close_polygon(); + + agg::polymorphic_renderer_solid_rgba8_base* ren = 0; + + //-- Polymorphic renderer class factory + switch(pix_fmt) + { + case agg::pix_format_rgb555 : ren = new agg::polymorphic_renderer_solid_rgba8_adaptor(rbuf_window()); break; + case agg::pix_format_rgb565 : ren = new agg::polymorphic_renderer_solid_rgba8_adaptor(rbuf_window()); break; + case agg::pix_format_rgb24 : ren = new agg::polymorphic_renderer_solid_rgba8_adaptor(rbuf_window()); break; + case agg::pix_format_bgr24 : ren = new agg::polymorphic_renderer_solid_rgba8_adaptor(rbuf_window()); break; + case agg::pix_format_rgba32 : ren = new agg::polymorphic_renderer_solid_rgba8_adaptor(rbuf_window()); break; + case agg::pix_format_argb32 : ren = new agg::polymorphic_renderer_solid_rgba8_adaptor(rbuf_window()); break; + case agg::pix_format_abgr32 : ren = new agg::polymorphic_renderer_solid_rgba8_adaptor(rbuf_window()); break; + case agg::pix_format_bgra32 : ren = new agg::polymorphic_renderer_solid_rgba8_adaptor(rbuf_window()); break; + } + + agg::rasterizer_scanline_aa<> ras; + agg::scanline_p8 sl; + if(ren) + { + ren->clear(agg::srgba8(255, 255, 255)); + ren->color(agg::srgba8(80, 30, 20)); + ras.add_path(path); + agg::render_scanlines(ras, sl, *ren); + } + delete ren; + } + +}; + + + +int agg_main(int argc, char* argv[]) +{ + the_application app(pix_fmt, flip_y); + app.caption("AGG Example. Polymorphic Renderers"); + + if(app.init(400, 330, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + diff --git a/examples/raster_text.cpp b/examples/raster_text.cpp new file mode 100644 index 0000000..60318b6 --- /dev/null +++ b/examples/raster_text.cpp @@ -0,0 +1,179 @@ +#include +#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_allocator.h" +#include "agg_span_gradient.h" +#include "agg_span_interpolator_linear.h" +#include "agg_glyph_raster_bin.h" +#include "agg_renderer_raster_text.h" +#include "agg_embedded_raster_fonts.h" +#include "platform/agg_platform_support.h" +#include "ctrl/agg_slider_ctrl.h" +#include "ctrl/agg_cbox_ctrl.h" + +#define AGG_BGR24 +//#define AGG_BGR96 +#include "pixel_formats.h" + +enum flip_y_e { flip_y = true }; + + + + +//------------------------------------------------------------------------ +template class gradient_sine_repeat_adaptor +{ +public: + gradient_sine_repeat_adaptor() : m_periods(agg::pi* 2.0) {} + + void periods(double p) { m_periods = p * agg::pi * 2.0; } + + int calculate(int x, int y, int d) const + { + return int((1.0 + sin(m_gradient.calculate(x, y, d) * m_periods / d)) * d/2); + } + +private: + GradientF m_gradient; + double m_periods; +}; + + + + +//------------------------------------------------------------------------ +class the_application : public agg::platform_support +{ +public: + typedef agg::renderer_base ren_base; + typedef agg::glyph_raster_bin glyph_gen; + + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y) + { + } + + + virtual void on_draw() + { + struct font_type + { + const agg::int8u* font; + const char* name; + } + fonts[] = + { + { agg::gse4x6, "gse4x6" }, + { agg::gse4x8, "gse4x8" }, + { agg::gse5x7, "gse5x7" }, + { agg::gse5x9, "gse5x9" }, + { agg::gse6x9, "gse6x9" }, + { agg::gse6x12, "gse6x12" }, + { agg::gse7x11, "gse7x11" }, + { agg::gse7x11_bold, "gse7x11_bold" }, + { agg::gse7x15, "gse7x15" }, + { agg::gse7x15_bold, "gse7x15_bold" }, + { agg::gse8x16, "gse8x16" }, + { agg::gse8x16_bold, "gse8x16_bold" }, + { agg::mcs11_prop, "mcs11_prop" }, + { agg::mcs11_prop_condensed, "mcs11_prop_condensed" }, + { agg::mcs12_prop, "mcs12_prop" }, + { agg::mcs13_prop, "mcs13_prop" }, + { agg::mcs5x10_mono, "mcs5x10_mono" }, + { agg::mcs5x11_mono, "mcs5x11_mono" }, + { agg::mcs6x10_mono, "mcs6x10_mono" }, + { agg::mcs6x11_mono, "mcs6x11_mono" }, + { agg::mcs7x12_mono_high, "mcs7x12_mono_high" }, + { agg::mcs7x12_mono_low, "mcs7x12_mono_low" }, + { agg::verdana12, "verdana12" }, + { agg::verdana12_bold, "verdana12_bold" }, + { agg::verdana13, "verdana13" }, + { agg::verdana13_bold, "verdana13_bold" }, + { agg::verdana14, "verdana14" }, + { agg::verdana14_bold, "verdana14_bold" }, + { agg::verdana16, "verdana16" }, + { agg::verdana16_bold, "verdana16_bold" }, + { agg::verdana17, "verdana17" }, + { agg::verdana17_bold, "verdana17_bold" }, + { agg::verdana18, "verdana18" }, + { agg::verdana18_bold, "verdana18_bold" }, + 0, 0 + }; + + + + glyph_gen glyph(0); + pixfmt pixf(rbuf_window()); + ren_base rb(pixf); + rb.clear(agg::rgba(1,1,1)); + + + agg::renderer_raster_htext_solid rt(rb, glyph); + + int i; + double y = 5; + rt.color(agg::rgba(0,0,0)); + for(i = 0; fonts[i].font; i++) + { + char buf[100]; + strcpy(buf, "A quick brown fox jumps over the lazy dog 0123456789: "); + strcat(buf, fonts[i].name); + + // Testing "wide-char" + unsigned wbuf[100]; + unsigned* wp = wbuf; + const char* p = buf; + while(*p) *wp++ = *(unsigned char*)p++; + *wp++ = 0; + + glyph.font(fonts[i].font); + rt.render_text(5, y, wbuf, !flip_y()); + y += glyph.height() + 1; + } + + + // Rendering raster text with a custom span generator, gradient + + typedef agg::span_interpolator_linear<> interpolator_type; + typedef agg::span_allocator span_alloc_type; + typedef agg::span_gradient, + agg::gradient_linear_color > span_gen_type; + typedef agg::renderer_scanline_aa ren_type; + + agg::trans_affine mtx; + gradient_sine_repeat_adaptor grad_func; + grad_func.periods(5); + agg::gradient_linear_color color_func; + color_func.colors(agg::rgba(1.0,0,0), agg::rgba(0,0.5,0)); + interpolator_type inter(mtx); + span_alloc_type sa; + span_gen_type sg(inter, grad_func, color_func, 0, 150.0); + ren_type ren(rb, sa, sg); + + agg::renderer_raster_htext rt2(ren, glyph); + rt2.render_text(5, 465, (unsigned char*)"RADIAL REPEATING GRADIENT: A quick brown fox jumps over the lazy dog", !flip_y()); + } + +}; + + +int agg_main(int argc, char* argv[]) +{ + the_application app(pix_format, flip_y); + app.caption("AGG Example. Raster Text"); + + if(app.init(640, 480, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + diff --git a/examples/rasterizer_compound.cpp b/examples/rasterizer_compound.cpp new file mode 100644 index 0000000..66ee1b4 --- /dev/null +++ b/examples/rasterizer_compound.cpp @@ -0,0 +1,273 @@ +#include +#include +#include "agg_basics.h" +#include "agg_ellipse.h" +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_rasterizer_compound_aa.h" +#include "agg_conv_curve.h" +#include "agg_conv_stroke.h" +#include "agg_scanline_u.h" +#include "agg_renderer_scanline.h" +#include "agg_span_allocator.h" +#include "agg_pixfmt_rgba.h" +#include "ctrl/agg_slider_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 }; + + +//------------------------------------------------- +class style_handler +{ +public: + style_handler(const color_type* styles, unsigned count) : + m_transparent(0, 0, 0, 0), + m_styles(styles), + m_count(count) + {} + + bool is_solid(unsigned style) const { return true; } + + const color_type& color(unsigned style) const + { + if (style < m_count) + return m_styles[style]; + + return m_transparent; + } + + void generate_span(color_type* span, int x, int y, unsigned len, unsigned style) + { + } + +private: + color_type m_transparent; + const color_type* m_styles; + unsigned m_count; +}; + + +class the_application : public agg::platform_support +{ + agg::slider_ctrl m_width; + agg::slider_ctrl m_alpha1; + agg::slider_ctrl m_alpha2; + agg::slider_ctrl m_alpha3; + agg::slider_ctrl m_alpha4; + agg::cbox_ctrl m_invert_order; + agg::path_storage m_path; + +public: + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_width(180 + 10.0, 5.0, 130 + 300.0, 12, !flip_y), + m_alpha1(5, 5, 180, 12, !flip_y), + m_alpha2(5, 25, 180, 32, !flip_y), + m_alpha3(5, 45, 180, 52, !flip_y), + m_alpha4(5, 65, 180, 72, !flip_y), + m_invert_order(190, 25, "Invert Z-Order") + { + add_ctrl(m_width); + m_width.range(-20.0, 50.0); + m_width.value(10.0); + m_width.label("Width=%1.2f"); + + add_ctrl(m_alpha1); + m_alpha1.range(0, 1); + m_alpha1.value(1); + m_alpha1.label("Alpha1=%1.3f"); + + add_ctrl(m_alpha2); + m_alpha2.range(0, 1); + m_alpha2.value(1); + m_alpha2.label("Alpha2=%1.3f"); + + add_ctrl(m_alpha3); + m_alpha3.range(0, 1); + m_alpha3.value(1); + m_alpha3.label("Alpha3=%1.3f"); + + add_ctrl(m_alpha4); + m_alpha4.range(0, 1); + m_alpha4.value(1); + m_alpha4.label("Alpha4=%1.3f"); + + add_ctrl(m_invert_order); + } + + void compose_path() + { + 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(); + } + + + + virtual void on_draw() + { + typedef agg::renderer_base ren_base; + typedef agg::renderer_base ren_base_pre; + + pixfmt pixf(rbuf_window()); + ren_base renb(pixf); + + pixfmt_pre pixf_pre(rbuf_window()); + ren_base_pre renb_pre(pixf_pre); + + // Clear the window with a gradient + agg::pod_vector gr(pixf_pre.width()); + unsigned i; + for(i = 0; i < pixf.width(); i++) + { + gr.add(agg::srgba8(255, 255, 0).gradient(agg::srgba8(0, 255, 255), + double(i) / pixf.width())); + } + for(i = 0; i < pixf.height(); i++) + { + renb.copy_color_hspan(0, i, pixf.width(), &gr[0]); + } + + agg::rasterizer_scanline_aa<> ras; + agg::rasterizer_compound_aa rasc; + agg::scanline_u8 sl; + agg::span_allocator alloc; + + // Draw two triangles + ras.move_to_d(0, 0); + ras.line_to_d(width(), 0); + ras.line_to_d(width(), height()); + agg::render_scanlines_aa_solid(ras, sl, renb, agg::srgba8(0, 100, 0)); + + ras.move_to_d(0, 0); + ras.line_to_d(0, height()); + ras.line_to_d(width(), 0); + agg::render_scanlines_aa_solid(ras, sl, renb, agg::srgba8(0, 100, 100)); + + agg::trans_affine mtx; + mtx *= agg::trans_affine_scaling(4.0); + mtx *= agg::trans_affine_translation(150, 100); + + agg::conv_transform trans(m_path, mtx); + agg::conv_curve > curve(trans); + + agg::conv_stroke + > > stroke(curve); + + compose_path(); + + color_type styles[4]; + + if(m_invert_order.status()) + { + rasc.layer_order(agg::layer_inverse); + } + else + { + rasc.layer_order(agg::layer_direct); + } + + styles[3] = agg::srgba8(255, 0, 108); + styles[2] = agg::srgba8(51, 0, 151); + styles[1] = agg::srgba8(143, 90, 6); + styles[0] = agg::srgba8(0, 0, 255); + + style_handler sh(styles, 4); + + stroke.width(m_width.value()); + + styles[3].opacity(m_alpha1.value()).premultiply(); + styles[2].opacity(m_alpha2.value()).premultiply(); + styles[1].opacity(m_alpha3.value()).premultiply(); + styles[0].opacity(m_alpha4.value()).premultiply(); + + agg::ellipse ell(220.0, 180.0, 120.0, 10.0, 128, false); + agg::conv_stroke str_ell(ell); + str_ell.width(m_width.value() / 2); + + rasc.styles(3, -1); + rasc.add_path(str_ell); + + rasc.styles(2, -1); + rasc.add_path(ell); + + rasc.styles(1, -1); + rasc.add_path(stroke); + + rasc.styles(0, -1); + rasc.add_path(curve); + + agg::render_scanlines_compound_layered(rasc, sl, renb_pre, alloc, sh); + agg::render_ctrl(ras, sl, renb, m_width); + agg::render_ctrl(ras, sl, renb, m_alpha1); + agg::render_ctrl(ras, sl, renb, m_alpha2); + agg::render_ctrl(ras, sl, renb, m_alpha3); + agg::render_ctrl(ras, sl, renb, m_alpha4); + agg::render_ctrl(ras, sl, renb, m_invert_order); + } + +}; + + + +int agg_main(int argc, char* argv[]) +{ + the_application app(pix_format, flip_y); + app.caption("AGG Example. Compound Rasterizer -- Geometry Flattening"); + + if(app.init(440, 330, 0)) + { + return app.run(); + } + return 1; +} diff --git a/examples/rasterizers.cpp b/examples/rasterizers.cpp new file mode 100644 index 0000000..db213fb --- /dev/null +++ b/examples/rasterizers.cpp @@ -0,0 +1,281 @@ +#include +#include +#include +#include "agg_basics.h" +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_rasterizer_outline.h" +#include "agg_scanline_p.h" +#include "agg_scanline_bin.h" +#include "agg_renderer_scanline.h" +#include "agg_renderer_primitives.h" +#include "ctrl/agg_slider_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::slider_ctrl m_gamma; + agg::slider_ctrl m_alpha; + agg::cbox_ctrl m_test; + agg::rasterizer_scanline_aa<> m_ras; + agg::scanline_p8 m_sl_p8; + agg::scanline_bin m_sl_bin; + + +public: + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_idx(-1), + m_gamma(130 + 10.0, 10.0 + 4.0, 130 + 150.0, 10.0 + 8.0 + 4.0, !flip_y), + m_alpha(130 + 150.0 + 10.0, 10.0 + 4.0, 500 - 10.0, 10.0 + 8.0 + 4.0, !flip_y), + m_test(130 + 10.0, 10.0 + 4.0 + 16.0, "Test Performance", !flip_y) + { + m_x[0] = 100 + 120; m_y[0] = 60; + m_x[1] = 369 + 120; m_y[1] = 170; + m_x[2] = 143 + 120; m_y[2] = 310; + + add_ctrl(m_gamma); + m_gamma.range(0.0, 1.0); + m_gamma.value(0.5); + m_gamma.label("Gamma=%1.2f"); + m_gamma.no_transform(); + + add_ctrl(m_alpha); + m_alpha.range(0.0, 1.0); + m_alpha.value(1.0); + m_alpha.label("Alpha=%1.2f"); + m_alpha.no_transform(); + + add_ctrl(m_test); + m_test.no_transform(); + } + + + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_aa; + typedef agg::renderer_scanline_bin_solid renderer_bin; + + + void draw_anti_aliased() + { + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_aa ren_aa(rb); + + agg::path_storage path; + + path.move_to(m_x[0], m_y[0]); + path.line_to(m_x[1], m_y[1]); + path.line_to(m_x[2], m_y[2]); + path.close_polygon(); + + ren_aa.color(agg::rgba(0.7, 0.5, 0.1, m_alpha.value())); + + m_ras.gamma(agg::gamma_power(m_gamma.value() * 2.0)); + m_ras.add_path(path); + agg::render_scanlines(m_ras, m_sl_p8, ren_aa); + } + + + void draw_aliased() + { + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_bin ren_bin(rb); + + agg::path_storage path; + + + path.move_to(m_x[0] - 200, m_y[0]); + path.line_to(m_x[1] - 200, m_y[1]); + path.line_to(m_x[2] - 200, m_y[2]); + path.close_polygon(); + + ren_bin.color(agg::rgba(0.1, 0.5, 0.7, m_alpha.value())); + + m_ras.gamma(agg::gamma_threshold(m_gamma.value())); + m_ras.add_path(path); + agg::render_scanlines(m_ras, m_sl_bin, ren_bin); + + //-- Drawing an outline with subpixel accuracy (aliased) + //typedef agg::renderer_primitives renderer_pr; + //renderer_pr ren_pr(rb); + //agg::rasterizer_outline ras_line(ren_pr); + //ren_pr.line_color(agg::rgba(0.0, 0.0, 0.0)); + //ras_line.add_path(path); + } + + virtual void on_draw() + { + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_aa ren_aa(rb); + + rb.clear(agg::rgba(1, 1, 1)); + + agg::rasterizer_scanline_aa<> ras_aa; + + draw_anti_aliased(); + draw_aliased(); + + agg::render_ctrl(ras_aa, m_sl_p8, rb, m_gamma); + agg::render_ctrl(ras_aa, m_sl_p8, rb, m_alpha); + agg::render_ctrl(ras_aa, m_sl_p8, rb, m_test); + } + + + 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 || + sqrt( (x-m_x[i]+200) * (x-m_x[i]+200) + (y-m_y[i]) * (y-m_y[i]) ) < 20) + { + 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) || + agg::point_in_triangle(m_x[0] - 200, m_y[0], + m_x[1] - 200, m_y[1], + m_x[2] - 200, 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_ctrl_change() + { + if(m_test.status()) + { + on_draw(); + update_window(); + m_test.status(false); + + start_timer(); + int i; + for(i = 0; i < 1000; i++) + { + draw_aliased(); + } + double t1 = elapsed_time(); + + start_timer(); + for(i = 0; i < 1000; i++) + { + draw_anti_aliased(); + } + double t2 = elapsed_time(); + + update_window(); + char buf[100]; + sprintf(buf, "Time Aliased=%.2fms Time Anti-Aliased=%.2fms", t1, t2); + message(buf); + } + } + + + 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, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + diff --git a/examples/rasterizers2.cpp b/examples/rasterizers2.cpp new file mode 100644 index 0000000..2970863 --- /dev/null +++ b/examples/rasterizers2.cpp @@ -0,0 +1,552 @@ +#include +#include +#include +#include "agg_basics.h" +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_rasterizer_outline.h" +#include "agg_conv_transform.h" +#include "agg_conv_stroke.h" +#include "agg_scanline_p.h" +#include "agg_renderer_scanline.h" +#include "agg_renderer_primitives.h" +#include "agg_rasterizer_outline.h" +#include "agg_rasterizer_outline_aa.h" +#include "agg_pattern_filters_rgba.h" +#include "agg_renderer_outline_aa.h" +#include "agg_renderer_outline_image.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_RGB565 +//#define AGG_RGB555 +#include "pixel_formats.h" + + +enum flip_y_e { flip_y = true }; + +static const agg::int32u pixmap_chain[] = +{ + 16, 7, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xb4c29999, 0xff9a5757, 0xff9a5757, 0xff9a5757, 0xff9a5757, 0xff9a5757, 0xff9a5757, 0xb4c29999, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x0cfbf9f9, 0xff9a5757, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xb4c29999, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x5ae0cccc, 0xffa46767, 0xff660000, 0xff975252, 0x7ed4b8b8, 0x5ae0cccc, 0x5ae0cccc, 0x5ae0cccc, 0x5ae0cccc, 0xa8c6a0a0, 0xff7f2929, 0xff670202, 0x9ecaa6a6, 0x5ae0cccc, 0x00ffffff, + 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xa4c7a2a2, 0x3affff00, 0x3affff00, 0xff975151, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, + 0x00ffffff, 0x5ae0cccc, 0xffa46767, 0xff660000, 0xff954f4f, 0x7ed4b8b8, 0x5ae0cccc, 0x5ae0cccc, 0x5ae0cccc, 0x5ae0cccc, 0xa8c6a0a0, 0xff7f2929, 0xff670202, 0x9ecaa6a6, 0x5ae0cccc, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x0cfbf9f9, 0xff9a5757, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xff660000, 0xb4c29999, 0x00ffffff, 0x00ffffff, 0x00ffffff, + 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0xb4c29999, 0xff9a5757, 0xff9a5757, 0xff9a5757, 0xff9a5757, 0xff9a5757, 0xff9a5757, 0xb4c29999, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff +}; + + + +namespace agg +{ + class pattern_pixmap_argb32 + { + public: + typedef rgba color_type; + + pattern_pixmap_argb32(const int32u* pixmap) : m_pixmap(pixmap) {} + + unsigned width() const { return m_pixmap[0]; } + unsigned height() const { return m_pixmap[1]; } + + rgba pixel(int x, int y) const + { + int32u p = m_pixmap[y * width() + x + 2]; + srgba8 c((p >> 16) & 0xFF, (p >> 8) & 0xFF, p & 0xFF, p >> 24); + return rgba(c).premultiply(); + } + private: + const int32u* m_pixmap; + }; +} + + + +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(8.0)), + m_dr(m_step / 45.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; +}; + + +struct roundoff +{ + void transform(double* x, double* y) const + { + *x = floor(*x); + *y = floor(*y); + } +}; + + +class the_application : public agg::platform_support +{ + agg::slider_ctrl m_step; + agg::slider_ctrl m_width; + agg::cbox_ctrl m_test; + agg::cbox_ctrl m_rotate; + agg::cbox_ctrl m_accurate_joins; + agg::cbox_ctrl m_scale_pattern; + double m_start_angle; + + +public: + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_aa; + typedef agg::renderer_primitives renderer_prim; + typedef agg::rasterizer_outline rasterizer_outline; + typedef agg::rasterizer_scanline_aa<> rasterizer_scanline; + typedef agg::scanline_p8 scanline; + typedef agg::renderer_outline_aa renderer_oaa; + typedef agg::pattern_filter_bilinear_rgba pattern_filter; + typedef agg::line_image_pattern_pow2 image_pattern; + typedef agg::renderer_outline_image renderer_img; + typedef agg::rasterizer_outline_aa rasterizer_outline_aa; + typedef agg::rasterizer_outline_aa rasterizer_outline_img; + + + + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_step(10.0, 10.0 + 4.0, 150.0, 10.0 + 8.0 + 4.0, !flip_y), + m_width(150.0 + 10.0, 10.0 + 4.0, 400 - 10.0, 10.0 + 8.0 + 4.0, !flip_y), + m_test(10.0, 10.0 + 4.0 + 16.0, "Test Performance", !flip_y), + m_rotate(130 + 10.0, 10.0 + 4.0 + 16.0, "Rotate", !flip_y), + m_accurate_joins(200 + 10.0, 10.0 + 4.0 + 16.0, "Accurate Joins", !flip_y), + m_scale_pattern(310 + 10.0, 10.0 + 4.0 + 16.0, "Scale Pattern", !flip_y), + m_start_angle(0.0) + { + add_ctrl(m_step); + m_step.range(0.0, 2.0); + m_step.value(0.1); + m_step.label("Step=%1.2f"); + m_step.no_transform(); + + add_ctrl(m_width); + m_width.range(0.0, 14.0); + m_width.value(3.0); + m_width.label("Width=%1.2f"); + m_width.no_transform(); + + add_ctrl(m_test); + m_test.text_size(9.0, 7.0); + m_test.no_transform(); + + add_ctrl(m_rotate); + m_rotate.text_size(9.0, 7.0); + m_rotate.no_transform(); + + add_ctrl(m_accurate_joins); + m_accurate_joins.text_size(9.0, 7.0); + m_accurate_joins.no_transform(); + + add_ctrl(m_scale_pattern); + m_scale_pattern.text_size(9.0, 7.0); + m_scale_pattern.no_transform(); + m_scale_pattern.status(true); + } + + + + void draw_aliased_pix_accuracy(rasterizer_outline& ras, renderer_prim& prim) + { + spiral s1(width()/5, height()/4+50, 5, 70, 16, m_start_angle); + roundoff rn; + agg::conv_transform trans(s1, rn); + prim.line_color(agg::rgba(0.4, 0.3, 0.1)); + ras.add_path(trans); + } + + void draw_aliased_subpix_accuracy(rasterizer_outline& ras, renderer_prim& prim) + { + spiral s2(width()/2, height()/4+50, 5, 70, 16, m_start_angle); + prim.line_color(agg::rgba(0.4, 0.3, 0.1)); + ras.add_path(s2); + } + + void draw_anti_aliased_outline(rasterizer_outline_aa& ras, renderer_oaa& ren) + { + spiral s3(width()/5, height() - height()/4 + 20, 5, 70, 16, m_start_angle); + ren.color(agg::rgba(0.4, 0.3, 0.1)); + ras.add_path(s3); + } + + void draw_anti_aliased_scanline(rasterizer_scanline& ras, scanline& sl, renderer_aa& ren) + { + spiral s4(width()/2, height() - height()/4 + 20, 5, 70, 16, m_start_angle); + agg::conv_stroke stroke(s4); + stroke.width(m_width.value()); + stroke.line_cap(agg::round_cap); + ren.color(agg::rgba(0.4, 0.3, 0.1)); + ras.add_path(stroke); + agg::render_scanlines(ras, sl, ren); + } + + void draw_anti_aliased_outline_img(rasterizer_outline_img& ras, renderer_img& ren) + { + spiral s5(width() - width()/5, height() - height()/4 + 20, 5, 70, 16, m_start_angle); + ras.add_path(s5); + } + + + + void text(rasterizer_scanline& ras, + scanline& sl, + renderer_aa& ren, + double x, double y, const char* txt) + { + agg::gsv_text t; + t.size(8); + t.text(txt); + t.start_point(x, y); + agg::conv_stroke stroke(t); + stroke.width(0.7); + ras.add_path(stroke); + ren.color(agg::rgba(0,0,0)); + agg::render_scanlines(ras, sl, ren); + } + + + + + virtual void on_draw() + { + pixfmt_pre pf(rbuf_window()); + renderer_base ren_base(pf); + renderer_aa ren_aa(ren_base); + renderer_prim ren_prim(ren_base); + rasterizer_scanline ras_aa; + scanline sl; + rasterizer_outline ras_al(ren_prim); + agg::line_profile_aa prof; + prof.width(m_width.value()); + renderer_oaa ren_oaa(ren_base, prof); + rasterizer_outline_aa ras_oaa(ren_oaa); + ras_oaa.line_join(m_accurate_joins.status() ? + agg::outline_miter_accurate_join : + agg::outline_round_join); + ras_oaa.round_cap(true); + + pattern_filter filter; + agg::pattern_pixmap_argb32 src(pixmap_chain); + agg::line_image_scale src_scaled(src, m_width.value()); + image_pattern pattern(filter); + if(m_scale_pattern.status()) + { + pattern.create(src_scaled); + } + else + { + pattern.create(src); + } + renderer_img ren_img(ren_base, pattern); + if(m_scale_pattern.status()) + { + ren_img.scale_x(m_width.value() / src.height()); + } + rasterizer_outline_img ras_img(ren_img); + + ren_base.clear(agg::rgba(1.0, 1.0, 0.95)); + + draw_aliased_pix_accuracy(ras_al, ren_prim); + draw_aliased_subpix_accuracy(ras_al, ren_prim); + draw_anti_aliased_outline(ras_oaa, ren_oaa); + draw_anti_aliased_scanline(ras_aa, sl, ren_aa); + draw_anti_aliased_outline_img(ras_img, ren_img); + + text(ras_aa, sl, ren_aa, 50, 80, "Bresenham lines,\n\nregular accuracy"); + text(ras_aa, sl, ren_aa, width()/2-50, 80, "Bresenham lines,\n\nsubpixel accuracy"); + text(ras_aa, sl, ren_aa, 50, height()/2+50, "Anti-aliased lines"); + text(ras_aa, sl, ren_aa, width()/2-50, height()/2+50, "Scanline rasterizer"); + text(ras_aa, sl, ren_aa, width() - width()/5 - 50, height()/2+50, "Arbitrary Image Pattern"); + + // The source colors of controls are "plain". + pixfmt pf2(rbuf_window()); + agg::renderer_base ren_base2(pf2); + agg::render_ctrl(ras_aa, sl, ren_base2, m_step); + agg::render_ctrl(ras_aa, sl, ren_base2, m_width); + agg::render_ctrl(ras_aa, sl, ren_base2, m_test); + agg::render_ctrl(ras_aa, sl, ren_base2, m_rotate); + agg::render_ctrl(ras_aa, sl, ren_base2, m_accurate_joins); + agg::render_ctrl(ras_aa, sl, ren_base2, m_scale_pattern); + + + +/* +// An example of using anti-aliased outline rasterizer. +// Uncomment it to see the result +// + +// Includes: +//#include "agg_pixfmt_rgb.h" // or another +//#include "agg_renderer_outline_aa.h" +//#include "agg_rasterizer_outline_aa.h" + +typedef agg::renderer_base base_ren_type; +typedef agg::renderer_outline_aa renderer_type; +typedef agg::rasterizer_outline_aa rasterizer_type; + +double width = 5.0; +//-- create with specifying width +//-- min_width=1.0, smoother_width=1.0 +//agg::line_profile_aa(width, agg::gamma_none()); + +//-- create uninitialized and set parameters +agg::line_profile_aa profile; +profile.gamma(agg::gamma_power(1.2)); //optional +profile.min_width(0.75); //optional +profile.smoother_width(3.0); //optional +profile.width(width); //mandatory! + +agg::pixfmt_bgr24 pixf(rbuf_window()); //or another +base_ren_type base_ren(pixf); +renderer_type ren(base_ren, profile); +ren.color(agg::srgba8(0,0,0)); //mandatory! +rasterizer_type ras(ren); +ras.round_cap(true); //optional +ras.accurate_join(true); //optional + +//-- move_to/line_to interface +ras.move_to_d(100, 100); +ras.line_to_d(150, 200); +ras.render(false); //false means "don't close + //the polygon", i.e. polyline + +//-- add_path interface +//-- doesn't require invoking render() +//ras.add_path(some_path); +*/ + + + + +/* +// An example of using image pattern outline rasterizer +// Uncomment it to see the result +// + +// Includes: +//#include "agg_pixfmt_rgb.h" // or another +//#include "agg_pattern_filters_rgba.h" // for all rgba-8-bit color formats +//#include "agg_renderer_outline_image.h" +//#include "agg_rasterizer_outline_aa.h" + + +agg::pattern_filter_bilinear_rgba8 fltr; // Filtering functor + +agg::pattern_pixmap_argb32 patt_src(pixmap_chain); // 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. + +// 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_pow2 pattern_type; + +typedef agg::renderer_base base_ren_type; +typedef agg::renderer_outline_image renderer_type; +typedef agg::rasterizer_outline_aa rasterizer_type; + +//-- Create with specifying the source +pattern_type patt(fltr, src); + +//-- Create uninitialized and set the source +//pattern_type patt(fltr); +//patt.create(src); + +agg::pixfmt_bgr24 pixf(rbuf_window()); //or another +base_ren_type base_ren(pixf); +renderer_type ren(base_ren, patt); +//ren.scale_x(1.3); // Optional +rasterizer_type ras(ren); + +//-- move_to/line_to interface +ras.move_to_d(100, 150); +ras.line_to_d(0, 0); +ras.line_to_d(300, 200); +//ras.line_to_d(10, 10); +ras.render(false); //false means "don't close + //the polygon", i.e. polyline + +//-- add_path interface +//-- doesn't require invoking render() +//ras.add_path(some_path); +*/ + + } + + + virtual void on_idle() + { + m_start_angle += agg::deg2rad(m_step.value()); + if(m_start_angle > agg::deg2rad(360.0)) m_start_angle -= agg::deg2rad(360.0); + force_redraw(); + } + + virtual void on_ctrl_change() + { + wait_mode(!m_rotate.status()); + + if(m_test.status()) + { + on_draw(); + update_window(); + + pixfmt_pre pf(rbuf_window()); + renderer_base ren_base(pf); + renderer_aa ren_aa(ren_base); + renderer_prim ren_prim(ren_base); + rasterizer_scanline ras_aa; + scanline sl; + rasterizer_outline ras_al(ren_prim); + agg::line_profile_aa prof; + prof.width(m_width.value()); + renderer_oaa ren_oaa(ren_base, prof); + rasterizer_outline_aa ras_oaa(ren_oaa); + ras_oaa.line_join(m_accurate_joins.status() ? + agg::outline_miter_accurate_join : + agg::outline_round_join); + ras_oaa.round_cap(true); + + pattern_filter filter; + agg::pattern_pixmap_argb32 src(pixmap_chain); + agg::line_image_scale src_scaled(src, m_width.value()); + image_pattern pattern(filter); + if(m_scale_pattern.status()) + { + pattern.create(src_scaled); + } + else + { + pattern.create(src); + } + renderer_img ren_img(ren_base, pattern); + if(m_scale_pattern.status()) + { + ren_img.scale_x(src.height() / m_width.value()); + } + rasterizer_outline_img ras_img(ren_img); + + unsigned i; + + start_timer(); + for(i = 0; i < 200; i++) + { + draw_aliased_subpix_accuracy(ras_al, ren_prim); + m_start_angle += agg::deg2rad(m_step.value()); + } + double t2 = elapsed_time(); + + start_timer(); + for(i = 0; i < 200; i++) + { + draw_anti_aliased_outline(ras_oaa, ren_oaa); + m_start_angle += agg::deg2rad(m_step.value()); + } + double t3 = elapsed_time(); + + start_timer(); + for(i = 0; i < 200; i++) + { + draw_anti_aliased_scanline(ras_aa, sl, ren_aa); + m_start_angle += agg::deg2rad(m_step.value()); + } + double t4 = elapsed_time(); + + start_timer(); + for(i = 0; i < 200; i++) + { + draw_anti_aliased_outline_img(ras_img, ren_img); + m_start_angle += agg::deg2rad(m_step.value()); + } + double t5 = elapsed_time(); + + m_test.status(false); + force_redraw(); + char buf[256]; + sprintf(buf, "Aliased=%1.2fms, Anti-Aliased=%1.2fms, Scanline=%1.2fms, Image-Pattern=%1.2fms", + t2, t3, t4, t5); + message(buf); + } + } +}; + + +int agg_main(int argc, char* argv[]) +{ + the_application app(pix_format, flip_y); + app.caption("AGG Example. Line Join"); + + if(app.init(500, 450, 0)) + { + return app.run(); + } + + return 1; +} + + diff --git a/examples/rounded_rect.cpp b/examples/rounded_rect.cpp new file mode 100644 index 0000000..231e9e8 --- /dev/null +++ b/examples/rounded_rect.cpp @@ -0,0 +1,161 @@ +#include +#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_pixfmt_rgb.h" +#include "agg_ellipse.h" +#include "agg_rounded_rect.h" +#include "agg_conv_stroke.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 }; + + +class the_application : public agg::platform_support +{ + double m_x[2]; + double m_y[2]; + double m_dx; + double m_dy; + int m_idx; + agg::slider_ctrl m_radius; + agg::slider_ctrl m_offset; + agg::cbox_ctrl m_white_on_black; + + +public: + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_idx(-1), + m_radius(10, 10, 600-10, 19, !flip_y), + m_offset(10, 10+20, 600-10, 19+20, !flip_y), + m_white_on_black(10, 10+40, "White on black") + { + m_x[0] = 100; m_y[0] = 100; + m_x[1] = 500; m_y[1] = 350; + add_ctrl(m_radius); + add_ctrl(m_offset); + add_ctrl(m_white_on_black); + + m_radius.label("radius=%4.3f"); + m_radius.range(0.0, 50.0); + m_radius.value(25.0); + + m_offset.label("subpixel offset=%4.3f"); + m_offset.range(-2.0, 3.0); + + m_white_on_black.text_color(agg::srgba8(127, 127, 127)); + m_white_on_black.inactive_color(agg::srgba8(127, 127, 127)); + } + + + virtual void on_draw() + { + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_solid; + + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_solid ren(rb); + + rb.clear(m_white_on_black.status() ? agg::rgba(0,0,0) : agg::rgba(1,1,1)); + + agg::rasterizer_scanline_aa<> ras; + agg::scanline_p8 sl; + + agg::ellipse e; + + // Render two "control" circles + ren.color(agg::srgba8(127,127,127)); + e.init(m_x[0], m_y[0], 3, 3, 16); + ras.add_path(e); + agg::render_scanlines(ras, sl, ren); + e.init(m_x[1], m_y[1], 3, 3, 16); + ras.add_path(e); + agg::render_scanlines(ras, sl, ren); + + double d = m_offset.value(); + + // Creating a rounded rectangle + agg::rounded_rect r(m_x[0]+d, m_y[0]+d, m_x[1]+d, m_y[1]+d, m_radius.value()); + r.normalize_radius(); + + // Drawing as an outline + agg::conv_stroke p(r); + p.width(1.0); + ras.add_path(p); + ren.color(m_white_on_black.status() ? agg::rgba(1,1,1) : agg::rgba(0,0,0)); + agg::render_scanlines(ras, sl, ren); + + // Render the controls + agg::render_ctrl(ras, sl, rb, m_radius); + agg::render_ctrl(ras, sl, rb, m_offset); + agg::render_ctrl(ras, sl, rb, m_white_on_black); + } + + + virtual void on_mouse_button_down(int x, int y, unsigned flags) + { + if(flags & agg::mouse_left) + { + unsigned i; + for (i = 0; i < 2; i++) + { + if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 5.0) + { + m_dx = x - m_x[i]; + m_dy = y - m_y[i]; + m_idx = i; + break; + } + } + } + } + + + virtual void on_mouse_move(int x, int y, unsigned flags) + { + if(flags & agg::mouse_left) + { + 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. Rounded rectangle"); + + if(app.init(600, 400, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + diff --git a/examples/scanline_boolean.cpp b/examples/scanline_boolean.cpp new file mode 100644 index 0000000..6c37241 --- /dev/null +++ b/examples/scanline_boolean.cpp @@ -0,0 +1,281 @@ +#include +#include +#include +#include "agg_basics.h" +#include "agg_array.h" +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_scanline_p.h" +#include "agg_scanline_u.h" +#include "agg_scanline_bin.h" +#include "agg_scanline_boolean_algebra.h" +#include "agg_scanline_storage_aa.h" +#include "agg_scanline_storage_bin.h" +#include "agg_renderer_scanline.h" +#include "agg_path_storage.h" +#include "agg_conv_transform.h" +#include "agg_ellipse.h" +#include "ctrl/agg_rbox_ctrl.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_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 }; + + + + + + + + + +void generate_circles(agg::path_storage& ps, + const double* quad, + unsigned num_circles, + double radius) +{ + ps.remove_all(); + unsigned i; + for(i = 0; i < 4; ++i) + { + unsigned n1 = i * 2; + unsigned n2 = (i < 3) ? i * 2 + 2 : 0; + unsigned j; + for(j = 0; j < num_circles; j++) + { + agg::ellipse ell(quad[n1] + (quad[n2] - quad[n1]) * j / num_circles, + quad[n1 + 1] + (quad[n2 + 1] - quad[n1 + 1]) * j / num_circles, + radius, radius, 100); + ps.concat_path(ell); + } + } +} + + + + + +class the_application : public agg::platform_support +{ +public: + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_solid; + typedef agg::scanline_p8 scanline_type; + + agg::interactive_polygon m_quad1; + agg::interactive_polygon m_quad2; + agg::rbox_ctrl m_trans_type; + agg::cbox_ctrl m_reset; + agg::slider_ctrl m_mul1; + agg::slider_ctrl m_mul2; + + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_quad1(4, 5.0), + m_quad2(4, 5.0), + m_trans_type(420, 5.0, 420+130.0, 145.0, !flip_y), + m_reset (350, 5.0, "Reset", !flip_y), + m_mul1 (5.0, 5.0, 340.0, 12.0, !flip_y), + m_mul2 (5.0, 20.0, 340.0, 27.0, !flip_y) + { + m_trans_type.add_item("Union"); + m_trans_type.add_item("Intersection"); + m_trans_type.add_item("Linear XOR"); + m_trans_type.add_item("Saddle XOR"); + m_trans_type.add_item("Abs Diff XOR"); + m_trans_type.add_item("A-B"); + m_trans_type.add_item("B-A"); + m_trans_type.cur_item(0); + add_ctrl(m_trans_type); + add_ctrl(m_reset); + add_ctrl(m_mul1); + add_ctrl(m_mul2); + m_mul1.value(1.0); + m_mul2.value(1.0); + m_mul1.label("Opacity1=%.3f"); + m_mul2.label("Opacity2=%.3f"); + } + + + virtual void on_init() + { + m_quad1.xn(0) = 50; + m_quad1.yn(0) = 200 - 20; + m_quad1.xn(1) = width() / 2 - 25; + m_quad1.yn(1) = 200; + m_quad1.xn(2) = width() / 2 - 25; + m_quad1.yn(2) = height() - 50 - 20; + m_quad1.xn(3) = 50; + m_quad1.yn(3) = height() - 50; + + m_quad2.xn(0) = width() / 2 + 25; + m_quad2.yn(0) = 200 - 20; + m_quad2.xn(1) = width() - 50; + m_quad2.yn(1) = 200; + m_quad2.xn(2) = width() - 50; + m_quad2.yn(2) = height() - 50 - 20; + m_quad2.xn(3) = width() / 2 + 25; + m_quad2.yn(3) = height() - 50; + } + + + + + virtual void on_draw() + { + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_solid r(rb); + rb.clear(agg::rgba(1, 1, 1)); + + scanline_type sl; + agg::rasterizer_scanline_aa<> ras; + agg::rasterizer_scanline_aa<> ras1; + agg::rasterizer_scanline_aa<> ras2; + + agg::sbool_op_e op = (agg::sbool_op_e)m_trans_type.cur_item(); + + ras1.gamma(agg::gamma_multiply(m_mul1.value())); + ras2.gamma(agg::gamma_multiply(m_mul2.value())); + + ras.clip_box(0, 0, width(), height()); + + agg::path_storage ps1; + generate_circles(ps1, m_quad1.polygon(), 5, 20); + + agg::path_storage ps2; + generate_circles(ps2, m_quad2.polygon(), 5, 20); + + ras1.filling_rule(agg::fill_even_odd); + + + r.color(agg::srgba8(240, 255, 200, 100)); + ras1.add_path(ps1); + agg::render_scanlines(ras1, sl, r); + + r.color(agg::srgba8(255, 240, 240, 100)); + ras2.add_path(ps2); + agg::render_scanlines(ras2, sl, r); + + + + typedef agg::scanline_p8 sbool_scanline_type; + typedef agg::renderer_scanline_aa_solid sbool_renderer_type; + + sbool_scanline_type sl_result; + sbool_scanline_type sl1; + sbool_scanline_type sl2; + sbool_renderer_type sren(rb); + + sren.color(agg::srgba8(0, 0, 0)); + + agg::sbool_combine_shapes_aa(op, ras1, ras2, sl1, sl2, sl_result, sren); + + //-------------------------- + // Render the "quad" tools and controls + r.color(agg::rgba(0, 0.3, 0.5, 0.6)); + ras.add_path(m_quad1); + agg::render_scanlines(ras, sl, r); + ras.add_path(m_quad2); + agg::render_scanlines(ras, sl, r); + agg::render_ctrl(ras, sl, rb, m_trans_type); + agg::render_ctrl(ras, sl, rb, m_reset); + agg::render_ctrl(ras, sl, rb, m_mul1); + agg::render_ctrl(ras, sl, rb, m_mul2); + //-------------------------- + + } + + + + virtual void on_mouse_button_down(int x, int y, unsigned flags) + { + if(flags & agg::mouse_left) + { + if(m_quad1.on_mouse_button_down(x, y) || + m_quad2.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_quad1.on_mouse_move(x, y) || + m_quad2.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_quad1.on_mouse_button_up(x, y) || + m_quad2.on_mouse_button_up(x, y) ) + { + force_redraw(); + } + } + + + virtual void on_ctrl_change() + { + if(m_reset.status()) + { + on_init(); + m_reset.status(false); + force_redraw(); + } + } +}; + + + + + + +int agg_main(int argc, char* argv[]) +{ + the_application app(pix_format, flip_y); + app.caption("AGG Example. Scanline Boolean"); + + if(app.init(800, 600, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + + + + + + + + + diff --git a/examples/scanline_boolean2.cpp b/examples/scanline_boolean2.cpp new file mode 100644 index 0000000..1818aa7 --- /dev/null +++ b/examples/scanline_boolean2.cpp @@ -0,0 +1,675 @@ +#include +#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_scanline_bin.h" +#include "agg_renderer_scanline.h" +#include "agg_renderer_primitives.h" +#include "agg_span_solid.h" +#include "agg_conv_curve.h" +#include "agg_conv_stroke.h" +#include "agg_gsv_text.h" +#include "agg_scanline_boolean_algebra.h" +#include "agg_scanline_storage_aa.h" +#include "agg_scanline_storage_bin.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; +}; + + + +template +unsigned count_spans(Rasterizer& ras, Scanline& sl) +{ + unsigned n = 0; + if(ras.rewind_scanlines()) + { + sl.reset(ras.min_x(), ras.max_x()); + while(ras.sweep_scanline(sl)) + { + n += sl.num_spans(); + } + } + return n; +} + + + +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 m_polygons; + agg::rbox_ctrl m_fill_rule; + agg::rbox_ctrl m_scanline_type; + agg::rbox_ctrl 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_fill_rule (200, 5.0, 200+105.0, 50.0, !flip_y), + m_scanline_type(300, 5.0, 300+115.0, 70.0, !flip_y), + m_operation (535.0, 5.0, 535.0+115.0, 145.0, !flip_y) + { + m_operation.add_item("None"); + m_operation.add_item("OR"); + m_operation.add_item("AND"); + m_operation.add_item("XOR Linear"); + m_operation.add_item("XOR Saddle"); + m_operation.add_item("A-B"); + m_operation.add_item("B-A"); + m_operation.cur_item(2); + add_ctrl(m_operation); + m_operation.no_transform(); + + m_fill_rule.add_item("Even-Odd"); + m_fill_rule.add_item("Non Zero"); + m_fill_rule.cur_item(1); + add_ctrl(m_fill_rule); + m_fill_rule.no_transform(); + + m_scanline_type.add_item("scanline_p"); + m_scanline_type.add_item("scanline_u"); + m_scanline_type.add_item("scanline_bin"); + m_scanline_type.cur_item(1); + add_ctrl(m_scanline_type); + m_scanline_type.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(); + } + + + + + template + void render_scanline_boolean(Rasterizer& ras1, Rasterizer& ras2) + { + if(m_operation.cur_item() > 0) + { + agg::sbool_op_e op; + switch(m_operation.cur_item()) + { + case 1: op = agg::sbool_or; break; + case 2: op = agg::sbool_and; break; + case 3: op = agg::sbool_xor; break; + case 4: op = agg::sbool_xor_saddle;break; + case 5: op = agg::sbool_a_minus_b; break; + case 6: op = agg::sbool_b_minus_a; break; + } + + typedef agg::renderer_base renderer_base; + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + + double t1 = 0.0; + double t2 = 0.0; + unsigned num_spans = 0; + + switch(m_scanline_type.cur_item()) + { + case 0: + { + typedef agg::renderer_scanline_aa_solid renderer_solid; + typedef agg::scanline_p8 scanline_type; + + renderer_solid ren(rb); + + scanline_type sl; + scanline_type sl1; + scanline_type sl2; + + // The intermediate storage is used only to test the perfoprmance, + // the short variant can be as follows: + // ------------------------ + // ren.color(agg::rgba(0.5, 0.0, 0, 0.5)); + // agg::sbool_combine_shapes_aa(op, ras1, ras2, sl1, sl2, sl, ren); + + agg::scanline_storage_aa8 storage; + agg::scanline_storage_aa8 storage1; + agg::scanline_storage_aa8 storage2; + + agg::render_scanlines(ras1, sl, storage1); + agg::render_scanlines(ras2, sl, storage2); + + start_timer(); + for(int i = 0; i < 10; i++) + { + agg::sbool_combine_shapes_aa(op, storage1, storage2, sl1, sl2, sl, storage); + } + t1 = elapsed_time() / 10.0; + + start_timer(); + ren.color(agg::rgba(0.5, 0.0, 0, 0.5)); + agg::render_scanlines(storage, sl, ren); + t2 = elapsed_time(); + + num_spans = count_spans(storage, sl); + } + break; + + case 1: + { + typedef agg::renderer_scanline_aa_solid renderer_solid; + typedef agg::scanline_u8 scanline_type; + + renderer_solid ren(rb); + + scanline_type sl; + scanline_type sl1; + scanline_type sl2; + agg::scanline_storage_aa8 storage; + agg::scanline_storage_aa8 storage1; + agg::scanline_storage_aa8 storage2; + + agg::render_scanlines(ras1, sl, storage1); + agg::render_scanlines(ras2, sl, storage2); + + start_timer(); + for(int i = 0; i < 10; i++) + { + agg::sbool_combine_shapes_aa(op, storage1, storage2, sl1, sl2, sl, storage); + } + t1 = elapsed_time() / 10.0; + + start_timer(); + ren.color(agg::rgba(0.5, 0.0, 0, 0.5)); + agg::render_scanlines(storage, sl, ren); + t2 = elapsed_time(); + + num_spans = count_spans(storage, sl); + } + break; + + + case 2: + { + typedef agg::renderer_scanline_bin_solid renderer_solid; + typedef agg::scanline_bin scanline_type; + + renderer_solid ren(rb); + + scanline_type sl; + scanline_type sl1; + scanline_type sl2; + + agg::scanline_storage_bin storage; + agg::scanline_storage_bin storage1; + agg::scanline_storage_bin storage2; + + agg::render_scanlines(ras1, sl, storage1); + agg::render_scanlines(ras2, sl, storage2); + + start_timer(); + for(int i = 0; i < 10; i++) + { + agg::sbool_combine_shapes_bin(op, storage1, storage2, sl1, sl2, sl, storage); + } + t1 = elapsed_time() / 10.0; + + start_timer(); + ren.color(agg::rgba(0.5, 0.0, 0, 0.5)); + agg::render_scanlines(storage, sl, ren); + t2 = elapsed_time(); + + num_spans = count_spans(storage, sl); + } + break; + + } + + + char buf[100]; + sprintf(buf, "Combine=%.3fms\n\nRender=%.3fms\n\nnum_spans=%d", t1, t2, num_spans); + agg::renderer_scanline_aa_solid ren(rb); + agg::scanline_p8 sl; + agg::gsv_text txt; + agg::conv_stroke txt_stroke(txt); + txt_stroke.width(1.0); + txt_stroke.line_cap(agg::round_cap); + txt.size(8.0); + txt.start_point(420, 40); + txt.text(buf); + ras1.add_path(txt_stroke); + ren.color(agg::rgba(0.0, 0.0, 0.0)); + agg::render_scanlines(ras1, sl, ren); + + + } + } + + + + + template + unsigned render_sbool(Rasterizer& ras1, Rasterizer& ras2) + { + pixfmt pf(rbuf_window()); + agg::renderer_base rb(pf); + agg::renderer_scanline_aa_solid > ren(rb); + agg::scanline_p8 sl; + + ras1.filling_rule(m_fill_rule.cur_item() ? agg::fill_non_zero : agg::fill_even_odd); + ras2.filling_rule(m_fill_rule.cur_item() ? agg::fill_non_zero : agg::fill_even_odd); + + 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+325, y+261); + ps1.line_to(x+268, y+309); + + 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); + + ras1.reset(); + ras1.add_path(ps1); + ren.color(agg::rgba(0, 0, 0, 0.1)); + agg::render_scanlines(ras1, sl, ren); + + ras2.reset(); + ras2.add_path(ps2); + ren.color(agg::rgba(0, 0.6, 0, 0.1)); + agg::render_scanlines(ras2, sl, ren); + + render_scanline_boolean(ras1, ras2); + } + break; + + case 1: + { + //------------------------------------ + // Closed stroke + // + agg::path_storage ps1; + agg::path_storage ps2; + agg::conv_stroke stroke(ps2); + stroke.width(15.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+363-50, y+249); + ps1.line_to(x+265-50, y+331); + ps1.close_polygon(); + + 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(); + + ras1.reset(); + ras1.add_path(ps1); + ren.color(agg::rgba(0, 0, 0, 0.1)); + agg::render_scanlines(ras1, sl, ren); + + ras2.reset(); + ras2.add_path(stroke); + ren.color(agg::rgba(0, 0.6, 0, 0.1)); + agg::render_scanlines(ras2, sl, ren); + + render_scanline_boolean(ras1, ras2); + } + 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 trans_gb_poly(gb_poly, mtx1); + agg::conv_transform trans_arrows(arrows, mtx2); + + ras2.add_path(trans_gb_poly); + ren.color(agg::rgba(0.5, 0.5, 0, 0.1)); + agg::render_scanlines(ras2, sl, ren); + + agg::conv_stroke > stroke_gb_poly(trans_gb_poly); + stroke_gb_poly.width(0.1); + ras1.add_path(stroke_gb_poly); + ren.color(agg::rgba(0, 0, 0)); + agg::render_scanlines(ras1, sl, ren); + + ras2.add_path(trans_arrows); + ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1)); + agg::render_scanlines(ras2, sl, ren); + + ras1.reset(); + ras1.add_path(trans_gb_poly); + + render_scanline_boolean(ras1, ras2); + } + break; + + + case 3: + { + //------------------------------------ + // Great Britain and a Spiral + // + spiral sp(m_x, m_y, 10, 150, 30, 0.0); + agg::conv_stroke 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); + mtx *= trans_affine_resizing(); + + agg::conv_transform trans_gb_poly(gb_poly, mtx); + + + ras1.add_path(trans_gb_poly); + ren.color(agg::rgba(0.5, 0.5, 0, 0.1)); + agg::render_scanlines(ras1, sl, ren); + + agg::conv_stroke > stroke_gb_poly(trans_gb_poly); + stroke_gb_poly.width(0.1); + ras1.reset(); + ras1.add_path(stroke_gb_poly); + ren.color(agg::rgba(0, 0, 0)); + agg::render_scanlines(ras1, sl, ren); + + ras2.reset(); + ras2.add_path(stroke); + ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1)); + agg::render_scanlines(ras2, sl, ren); + + ras1.reset(); + ras1.add_path(trans_gb_poly); + render_scanline_boolean(ras1, ras2); + } + break; + + + case 4: + { + //------------------------------------ + // Spiral and glyph + // + spiral sp(m_x, m_y, 10, 150, 30, 0.0); + agg::conv_stroke 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 trans(glyph, mtx); + agg::conv_curve > curve(trans); + + ras1.reset(); + ras1.add_path(stroke); + ren.color(agg::rgba(0, 0, 0, 0.1)); + agg::render_scanlines(ras1, sl, ren); + + ras2.reset(); + ras2.add_path(curve); + ren.color(agg::rgba(0, 0.6, 0, 0.1)); + agg::render_scanlines(ras2, sl, ren); + + render_scanline_boolean(ras1, ras2); + } + 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 base_ren_type; + typedef agg::renderer_scanline_aa_solid renderer_solid; + + pixfmt pf(rbuf_window()); + base_ren_type ren_base(pf); + renderer_solid ren_solid(ren_base); + ren_base.clear(agg::rgba(1,1,1)); + + agg::scanline_u8 sl; + agg::rasterizer_scanline_aa<> ras; + agg::rasterizer_scanline_aa<> ras2; + + agg::render_ctrl(ras, sl, ren_base, m_polygons); + agg::render_ctrl(ras, sl, ren_base, m_fill_rule); + agg::render_ctrl(ras, sl, ren_base, m_scanline_type); + agg::render_ctrl(ras, sl, ren_base, m_operation); + + render_sbool(ras, ras2); + + } + + + + + 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. Scanline Boolean"); + + if(app.init(655, 520, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + diff --git a/examples/simple_blur.cpp b/examples/simple_blur.cpp new file mode 100644 index 0000000..613c283 --- /dev/null +++ b/examples/simple_blur.cpp @@ -0,0 +1,260 @@ +#include +#include +#include +#include "agg_basics.h" +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_rasterizer_outline.h" +#include "agg_path_storage.h" +#include "agg_conv_stroke.h" +#include "agg_conv_transform.h" +#include "agg_bounding_rect.h" +#include "agg_scanline_u.h" +#include "agg_scanline_p.h" +#include "agg_pixfmt_rgb.h" +#include "agg_renderer_base.h" +#include "agg_renderer_outline_aa.h" +#include "agg_rasterizer_outline_aa.h" +#include "agg_renderer_scanline.h" +#include "agg_span_allocator.h" +#include "agg_ellipse.h" +#include "platform/agg_platform_support.h" + +// Note: example currently only supports 8-bit color +#define AGG_BGR24 +#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 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; +} + + +template class span_simple_blur_rgb24 +{ +public: + //-------------------------------------------------------------------- + span_simple_blur_rgb24() : m_source_image(0) {} + + //-------------------------------------------------------------------- + span_simple_blur_rgb24(const agg::rendering_buffer& src) : + m_source_image(&src) {} + + //-------------------------------------------------------------------- + void source_image(const agg::rendering_buffer& src) { m_source_image = &src; } + const agg::rendering_buffer& source_image() const { return *m_source_image; } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, int len) + { + if(y < 1 || y >= int(m_source_image->height() - 1)) + { + do + { + *span++ = color_type::no_color(); + } + while(--len); + return; + } + + do + { + color_type::calc_type color[3]; + color[0] = color[1] = color[2] = 0; + if(x > 0 && x < int(m_source_image->width()-1)) + { + int i = 3; + do + { + const agg::int8u* ptr = m_source_image->row_ptr(y - i + 2) + (x - 1) * 3; + + color[0] += *ptr++; + color[1] += *ptr++; + color[2] += *ptr++; + + color[0] += *ptr++; + color[1] += *ptr++; + color[2] += *ptr++; + + color[0] += *ptr++; + color[1] += *ptr++; + color[2] += *ptr++; + } + while(--i); + color[0] /= 9; + color[1] /= 9; + color[2] /= 9; + } + *span++ = color_type(color[Order::R], color[Order::G], color[Order::B]); + ++x; + } + while(--len); + } + +private: + const agg::rendering_buffer* m_source_image; +}; + + +class the_application : public agg::platform_support +{ + double m_cx; + double m_cy; + +public: + virtual ~the_application() + { + } + + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_cx(100), + m_cy(102) + { + parse_lion(); + } + + virtual void on_resize(int cx, int cy) + { + } + + virtual void on_draw() + { + typedef agg::renderer_base renderer_base; + typedef agg::renderer_scanline_aa_solid renderer_solid; + + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_solid rs(rb); + + rb.clear(agg::rgba(1, 1, 1)); + + agg::trans_affine mtx; + agg::conv_transform trans(g_path, 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(initial_width()/4, initial_height()/2); + mtx *= trans_affine_resizing(); + + agg::rasterizer_scanline_aa<> ras2; + agg::scanline_p8 sl; + agg::scanline_u8 sl2; + + agg::render_all_paths(ras2, sl, rs, trans, g_colors, g_path_idx, g_npaths); + + mtx *= ~trans_affine_resizing(); + mtx *= agg::trans_affine_translation(initial_width()/2, 0); + mtx *= trans_affine_resizing(); + + agg::line_profile_aa profile; + profile.width(1.0); + agg::renderer_outline_aa rp(rb, profile); + agg::rasterizer_outline_aa > ras(rp); + ras.round_cap(true); + + ras.render_all_paths(trans, g_colors, g_path_idx, g_npaths); + + agg::ellipse ell(m_cx, m_cy, 100.0, 100.0, 100); + agg::conv_stroke ell_stroke1(ell); + ell_stroke1.width(6.0); + agg::conv_stroke > ell_stroke2(ell_stroke1); + + ell_stroke2.width(2.0); + rs.color(agg::rgba(0,0.2,0)); + ras2.add_path(ell_stroke2); + agg::render_scanlines(ras2, sl, rs); + + typedef span_simple_blur_rgb24 span_blur_gen; + typedef agg::span_allocator span_blur_alloc; + + span_blur_alloc sa; + span_blur_gen sg; + + sg.source_image(rbuf_img(0)); + ras2.add_path(ell); + + copy_window_to_img(0); + agg::render_scanlines_aa(ras2, sl2, rb, sa, sg); + + // More blur if desired :-) + //copy_window_to_img(0); + //agg::render_scanlines(ras2, sl2, rblur); + //copy_window_to_img(0); + //agg::render_scanlines(ras2, sl2, rblur); + //copy_window_to_img(0); + //agg::render_scanlines(ras2, sl2, rblur); + } + + + virtual void on_mouse_button_down(int x, int y, unsigned flags) + { + if(flags & agg::mouse_left) + { + m_cx = x; + m_cy = 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; +} + + + + + + diff --git a/examples/svg_viewer/agg_svg_exception.h b/examples/svg_viewer/agg_svg_exception.h new file mode 100644 index 0000000..2a49b99 --- /dev/null +++ b/examples/svg_viewer/agg_svg_exception.h @@ -0,0 +1,69 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.3 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// SVG exception +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SVG_EXCEPTION_INCLUDED +#define AGG_SVG_EXCEPTION_INCLUDED + +#include +#include +#include + +namespace agg +{ +namespace svg +{ + class exception + { + public: + ~exception() + { + delete [] m_msg; + } + + exception() : m_msg(0) {} + + exception(const char* fmt, ...) : + m_msg(0) + { + if(fmt) + { + m_msg = new char [4096]; + va_list arg; + va_start(arg, fmt); + vsprintf(m_msg, fmt, arg); + va_end(arg); + } + } + + exception(const exception& exc) : + m_msg(exc.m_msg ? new char[strlen(exc.m_msg) + 1] : 0) + { + if(m_msg) strcpy(m_msg, exc.m_msg); + } + + const char* msg() const { return m_msg; } + + private: + char* m_msg; + }; + +} +} + +#endif diff --git a/examples/svg_viewer/agg_svg_parser.cpp b/examples/svg_viewer/agg_svg_parser.cpp new file mode 100644 index 0000000..5d7c764 --- /dev/null +++ b/examples/svg_viewer/agg_svg_parser.cpp @@ -0,0 +1,953 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.3 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// Copyright (c) 2008 Rene Rebe [ellipse and circle code] +// +// 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 +//---------------------------------------------------------------------------- +// +// SVG parser. +// +//---------------------------------------------------------------------------- + +#include +#include +#include +#include "agg_svg_parser.h" +#include "expat.h" + +namespace agg +{ +namespace svg +{ + struct named_color + { + char name[22]; + int8u r, g, b, a; + }; + + named_color colors[] = + { + { "aliceblue",240,248,255, 255 }, + { "antiquewhite",250,235,215, 255 }, + { "aqua",0,255,255, 255 }, + { "aquamarine",127,255,212, 255 }, + { "azure",240,255,255, 255 }, + { "beige",245,245,220, 255 }, + { "bisque",255,228,196, 255 }, + { "black",0,0,0, 255 }, + { "blanchedalmond",255,235,205, 255 }, + { "blue",0,0,255, 255 }, + { "blueviolet",138,43,226, 255 }, + { "brown",165,42,42, 255 }, + { "burlywood",222,184,135, 255 }, + { "cadetblue",95,158,160, 255 }, + { "chartreuse",127,255,0, 255 }, + { "chocolate",210,105,30, 255 }, + { "coral",255,127,80, 255 }, + { "cornflowerblue",100,149,237, 255 }, + { "cornsilk",255,248,220, 255 }, + { "crimson",220,20,60, 255 }, + { "cyan",0,255,255, 255 }, + { "darkblue",0,0,139, 255 }, + { "darkcyan",0,139,139, 255 }, + { "darkgoldenrod",184,134,11, 255 }, + { "darkgray",169,169,169, 255 }, + { "darkgreen",0,100,0, 255 }, + { "darkgrey",169,169,169, 255 }, + { "darkkhaki",189,183,107, 255 }, + { "darkmagenta",139,0,139, 255 }, + { "darkolivegreen",85,107,47, 255 }, + { "darkorange",255,140,0, 255 }, + { "darkorchid",153,50,204, 255 }, + { "darkred",139,0,0, 255 }, + { "darksalmon",233,150,122, 255 }, + { "darkseagreen",143,188,143, 255 }, + { "darkslateblue",72,61,139, 255 }, + { "darkslategray",47,79,79, 255 }, + { "darkslategrey",47,79,79, 255 }, + { "darkturquoise",0,206,209, 255 }, + { "darkviolet",148,0,211, 255 }, + { "deeppink",255,20,147, 255 }, + { "deepskyblue",0,191,255, 255 }, + { "dimgray",105,105,105, 255 }, + { "dimgrey",105,105,105, 255 }, + { "dodgerblue",30,144,255, 255 }, + { "firebrick",178,34,34, 255 }, + { "floralwhite",255,250,240, 255 }, + { "forestgreen",34,139,34, 255 }, + { "fuchsia",255,0,255, 255 }, + { "gainsboro",220,220,220, 255 }, + { "ghostwhite",248,248,255, 255 }, + { "gold",255,215,0, 255 }, + { "goldenrod",218,165,32, 255 }, + { "gray",128,128,128, 255 }, + { "green",0,128,0, 255 }, + { "greenyellow",173,255,47, 255 }, + { "grey",128,128,128, 255 }, + { "honeydew",240,255,240, 255 }, + { "hotpink",255,105,180, 255 }, + { "indianred",205,92,92, 255 }, + { "indigo",75,0,130, 255 }, + { "ivory",255,255,240, 255 }, + { "khaki",240,230,140, 255 }, + { "lavender",230,230,250, 255 }, + { "lavenderblush",255,240,245, 255 }, + { "lawngreen",124,252,0, 255 }, + { "lemonchiffon",255,250,205, 255 }, + { "lightblue",173,216,230, 255 }, + { "lightcoral",240,128,128, 255 }, + { "lightcyan",224,255,255, 255 }, + { "lightgoldenrodyellow",250,250,210, 255 }, + { "lightgray",211,211,211, 255 }, + { "lightgreen",144,238,144, 255 }, + { "lightgrey",211,211,211, 255 }, + { "lightpink",255,182,193, 255 }, + { "lightsalmon",255,160,122, 255 }, + { "lightseagreen",32,178,170, 255 }, + { "lightskyblue",135,206,250, 255 }, + { "lightslategray",119,136,153, 255 }, + { "lightslategrey",119,136,153, 255 }, + { "lightsteelblue",176,196,222, 255 }, + { "lightyellow",255,255,224, 255 }, + { "lime",0,255,0, 255 }, + { "limegreen",50,205,50, 255 }, + { "linen",250,240,230, 255 }, + { "magenta",255,0,255, 255 }, + { "maroon",128,0,0, 255 }, + { "mediumaquamarine",102,205,170, 255 }, + { "mediumblue",0,0,205, 255 }, + { "mediumorchid",186,85,211, 255 }, + { "mediumpurple",147,112,219, 255 }, + { "mediumseagreen",60,179,113, 255 }, + { "mediumslateblue",123,104,238, 255 }, + { "mediumspringgreen",0,250,154, 255 }, + { "mediumturquoise",72,209,204, 255 }, + { "mediumvioletred",199,21,133, 255 }, + { "midnightblue",25,25,112, 255 }, + { "mintcream",245,255,250, 255 }, + { "mistyrose",255,228,225, 255 }, + { "moccasin",255,228,181, 255 }, + { "navajowhite",255,222,173, 255 }, + { "navy",0,0,128, 255 }, + { "oldlace",253,245,230, 255 }, + { "olive",128,128,0, 255 }, + { "olivedrab",107,142,35, 255 }, + { "orange",255,165,0, 255 }, + { "orangered",255,69,0, 255 }, + { "orchid",218,112,214, 255 }, + { "palegoldenrod",238,232,170, 255 }, + { "palegreen",152,251,152, 255 }, + { "paleturquoise",175,238,238, 255 }, + { "palevioletred",219,112,147, 255 }, + { "papayawhip",255,239,213, 255 }, + { "peachpuff",255,218,185, 255 }, + { "peru",205,133,63, 255 }, + { "pink",255,192,203, 255 }, + { "plum",221,160,221, 255 }, + { "powderblue",176,224,230, 255 }, + { "purple",128,0,128, 255 }, + { "red",255,0,0, 255 }, + { "rosybrown",188,143,143, 255 }, + { "royalblue",65,105,225, 255 }, + { "saddlebrown",139,69,19, 255 }, + { "salmon",250,128,114, 255 }, + { "sandybrown",244,164,96, 255 }, + { "seagreen",46,139,87, 255 }, + { "seashell",255,245,238, 255 }, + { "sienna",160,82,45, 255 }, + { "silver",192,192,192, 255 }, + { "skyblue",135,206,235, 255 }, + { "slateblue",106,90,205, 255 }, + { "slategray",112,128,144, 255 }, + { "slategrey",112,128,144, 255 }, + { "snow",255,250,250, 255 }, + { "springgreen",0,255,127, 255 }, + { "steelblue",70,130,180, 255 }, + { "tan",210,180,140, 255 }, + { "teal",0,128,128, 255 }, + { "thistle",216,191,216, 255 }, + { "tomato",255,99,71, 255 }, + { "turquoise",64,224,208, 255 }, + { "violet",238,130,238, 255 }, + { "wheat",245,222,179, 255 }, + { "white",255,255,255, 255 }, + { "whitesmoke",245,245,245, 255 }, + { "yellow",255,255,0, 255 }, + { "yellowgreen",154,205,50, 255 }, + { "zzzzzzzzzzz",0,0,0, 0 } + }; + + + //------------------------------------------------------------------------ + parser::~parser() + { + delete [] m_attr_value; + delete [] m_attr_name; + delete [] m_buf; + delete [] m_title; + } + + //------------------------------------------------------------------------ + parser::parser(path_renderer& path) : + m_path(path), + m_tokenizer(), + m_buf(new char[buf_size]), + m_title(new char[256]), + m_title_len(0), + m_title_flag(false), + m_path_flag(false), + m_attr_name(new char[128]), + m_attr_value(new char[1024]), + m_attr_name_len(127), + m_attr_value_len(1023) + { + m_title[0] = 0; + } + + //------------------------------------------------------------------------ + void parser::parse(const char* fname) + { + char msg[1024]; + XML_Parser p = XML_ParserCreate(NULL); + if(p == 0) + { + throw exception("Couldn't allocate memory for parser"); + } + + XML_SetUserData(p, this); + XML_SetElementHandler(p, start_element, end_element); + XML_SetCharacterDataHandler(p, content); + + FILE* fd = fopen(fname, "r"); + if(fd == 0) + { + sprintf(msg, "Couldn't open file %s", fname); + throw exception(msg); + } + + bool done = false; + do + { + size_t len = fread(m_buf, 1, buf_size, fd); + done = len < buf_size; + if(!XML_Parse(p, m_buf, len, done)) + { + sprintf(msg, + "%s at line %lu\n", + XML_ErrorString(XML_GetErrorCode(p)), + XML_GetCurrentLineNumber(p)); + throw exception(msg); + } + } + while(!done); + fclose(fd); + XML_ParserFree(p); + + char* ts = m_title; + while(*ts) + { + if(*ts < ' ') *ts = ' '; + ++ts; + } + } + + + //------------------------------------------------------------------------ + void parser::start_element(void* data, const char* el, const char** attr) + { + parser& self = *(parser*)data; + + if(strcmp(el, "title") == 0) + { + self.m_title_flag = true; + } + else + if(strcmp(el, "g") == 0) + { + self.m_path.push_attr(); + self.parse_attr(attr); + } + else + if(strcmp(el, "path") == 0) + { + if(self.m_path_flag) + { + throw exception("start_element: Nested path"); + } + self.m_path.begin_path(); + self.parse_path(attr); + self.m_path.end_path(); + self.m_path_flag = true; + } + else + if(strcmp(el, "rect") == 0) + { + self.parse_rect(attr); + } + else + if(strcmp(el, "line") == 0) + { + self.parse_line(attr); + } + else + if(strcmp(el, "polyline") == 0) + { + self.parse_poly(attr, false); + } + else + if(strcmp(el, "polygon") == 0) + { + self.parse_poly(attr, true); + } + else + if(strcmp(el, "circle") == 0) + { + self.parse_circle(attr); + } + else + if(strcmp(el, "ellipse") == 0) + { + self.parse_ellipse(attr); + } + //else + //if(strcmp(el, "") == 0) + //{ + //} + // . . . + } + + + //------------------------------------------------------------------------ + void parser::end_element(void* data, const char* el) + { + parser& self = *(parser*)data; + + if(strcmp(el, "title") == 0) + { + self.m_title_flag = false; + } + else + if(strcmp(el, "g") == 0) + { + self.m_path.pop_attr(); + } + else + if(strcmp(el, "path") == 0) + { + self.m_path_flag = false; + } + //else + //if(strcmp(el, "") == 0) + //{ + //} + // . . . + } + + + //------------------------------------------------------------------------ + void parser::content(void* data, const char* s, int len) + { + parser& self = *(parser*)data; + + // m_title_flag signals that the tag is being parsed now. + // The following code concatenates the pieces of content of the <title> tag. + if(self.m_title_flag) + { + if(len + self.m_title_len > 255) len = 255 - self.m_title_len; + if(len > 0) + { + memcpy(self.m_title + self.m_title_len, s, len); + self.m_title_len += len; + self.m_title[self.m_title_len] = 0; + } + } + } + + + //------------------------------------------------------------------------ + void parser::parse_attr(const char** attr) + { + int i; + for(i = 0; attr[i]; i += 2) + { + if(strcmp(attr[i], "style") == 0) + { + parse_style(attr[i + 1]); + } + else + { + parse_attr(attr[i], attr[i + 1]); + } + } + } + + //------------------------------------------------------------- + void parser::parse_path(const char** attr) + { + int i; + + for(i = 0; attr[i]; i += 2) + { + // The <path> tag can consist of the path itself ("d=") + // as well as of other parameters like "style=", "transform=", etc. + // In the last case we simply rely on the function of parsing + // attributes (see 'else' branch). + if(strcmp(attr[i], "d") == 0) + { + m_tokenizer.set_path_str(attr[i + 1]); + m_path.parse_path(m_tokenizer); + } + else + { + // Create a temporary single pair "name-value" in order + // to avoid multiple calls for the same attribute. + const char* tmp[4]; + tmp[0] = attr[i]; + tmp[1] = attr[i + 1]; + tmp[2] = 0; + tmp[3] = 0; + parse_attr(tmp); + } + } + } + + + //------------------------------------------------------------- + int cmp_color(const void* p1, const void* p2) + { + return strcmp(((named_color*)p1)->name, ((named_color*)p2)->name); + } + + //------------------------------------------------------------- + rgba8 parse_color(const char* str) + { + while(*str == ' ') ++str; + unsigned c = 0; + if(*str == '#') + { + sscanf(str + 1, "%x", &c); + return rgb8_packed(c); + } + else + { + named_color c; + unsigned len = strlen(str); + if(len > sizeof(c.name) - 1) + { + throw exception("parse_color: Invalid color name '%s'", str); + } + strcpy(c.name, str); + const void* p = bsearch(&c, + colors, + sizeof(colors) / sizeof(colors[0]), + sizeof(colors[0]), + cmp_color); + if(p == 0) + { + throw exception("parse_color: Invalid color name '%s'", str); + } + const named_color* pc = (const named_color*)p; + return rgba8(pc->r, pc->g, pc->b, pc->a); + } + } + + double parse_double(const char* str) + { + while(*str == ' ') ++str; + return atof(str); + } + + + + //------------------------------------------------------------- + bool parser::parse_attr(const char* name, const char* value) + { + if(strcmp(name, "style") == 0) + { + parse_style(value); + } + else + if(strcmp(name, "fill") == 0) + { + if(strcmp(value, "none") == 0) + { + m_path.fill_none(); + } + else + { + m_path.fill(parse_color(value)); + } + } + else + if(strcmp(name, "fill-opacity") == 0) + { + m_path.fill_opacity(parse_double(value)); + } + else + if(strcmp(name, "stroke") == 0) + { + if(strcmp(value, "none") == 0) + { + m_path.stroke_none(); + } + else + { + m_path.stroke(parse_color(value)); + } + } + else + if(strcmp(name, "stroke-width") == 0) + { + m_path.stroke_width(parse_double(value)); + } + else + if(strcmp(name, "stroke-linecap") == 0) + { + if(strcmp(value, "butt") == 0) m_path.line_cap(butt_cap); + else if(strcmp(value, "round") == 0) m_path.line_cap(round_cap); + else if(strcmp(value, "square") == 0) m_path.line_cap(square_cap); + } + else + if(strcmp(name, "stroke-linejoin") == 0) + { + if(strcmp(value, "miter") == 0) m_path.line_join(miter_join); + else if(strcmp(value, "round") == 0) m_path.line_join(round_join); + else if(strcmp(value, "bevel") == 0) m_path.line_join(bevel_join); + } + else + if(strcmp(name, "stroke-miterlimit") == 0) + { + m_path.miter_limit(parse_double(value)); + } + else + if(strcmp(name, "stroke-opacity") == 0) + { + m_path.stroke_opacity(parse_double(value)); + } + else + if(strcmp(name, "transform") == 0) + { + parse_transform(value); + } + else + if(strcmp(name, "fill-rule") == 0) + { + m_path.even_odd(strcmp(value, "evenodd") == 0); + } + //else + //if(strcmp(el, "<OTHER_ATTRIBUTES>") == 0) + //{ + //} + // . . . + else + { + return false; + } + return true; + } + + + + //------------------------------------------------------------- + void parser::copy_name(const char* start, const char* end) + { + unsigned len = unsigned(end - start); + if(m_attr_name_len == 0 || len > m_attr_name_len) + { + delete [] m_attr_name; + m_attr_name = new char[len + 1]; + m_attr_name_len = len; + } + if(len) memcpy(m_attr_name, start, len); + m_attr_name[len] = 0; + } + + + + //------------------------------------------------------------- + void parser::copy_value(const char* start, const char* end) + { + unsigned len = unsigned(end - start); + if(m_attr_value_len == 0 || len > m_attr_value_len) + { + delete [] m_attr_value; + m_attr_value = new char[len + 1]; + m_attr_value_len = len; + } + if(len) memcpy(m_attr_value, start, len); + m_attr_value[len] = 0; + } + + + //------------------------------------------------------------- + bool parser::parse_name_value(const char* nv_start, const char* nv_end) + { + const char* str = nv_start; + while(str < nv_end && *str != ':') ++str; + + const char* val = str; + + // Right Trim + while(str > nv_start && + (*str == ':' || isspace(*str))) --str; + ++str; + + copy_name(nv_start, str); + + while(val < nv_end && (*val == ':' || isspace(*val))) ++val; + + copy_value(val, nv_end); + return parse_attr(m_attr_name, m_attr_value); + } + + + + //------------------------------------------------------------- + void parser::parse_style(const char* str) + { + while(*str) + { + // Left Trim + while(*str && isspace(*str)) ++str; + const char* nv_start = str; + while(*str && *str != ';') ++str; + const char* nv_end = str; + + // Right Trim + while(nv_end > nv_start && + (*nv_end == ';' || isspace(*nv_end))) --nv_end; + ++nv_end; + + parse_name_value(nv_start, nv_end); + if(*str) ++str; + } + + } + + + //------------------------------------------------------------- + void parser::parse_rect(const char** attr) + { + int i; + double x = 0.0; + double y = 0.0; + double w = 0.0; + double h = 0.0; + + m_path.begin_path(); + for(i = 0; attr[i]; i += 2) + { + if(!parse_attr(attr[i], attr[i + 1])) + { + if(strcmp(attr[i], "x") == 0) x = parse_double(attr[i + 1]); + if(strcmp(attr[i], "y") == 0) y = parse_double(attr[i + 1]); + if(strcmp(attr[i], "width") == 0) w = parse_double(attr[i + 1]); + if(strcmp(attr[i], "height") == 0) h = parse_double(attr[i + 1]); + // rx - to be implemented + // ry - to be implemented + } + } + + + if(w != 0.0 && h != 0.0) + { + if(w < 0.0) throw exception("parse_rect: Invalid width: %f", w); + if(h < 0.0) throw exception("parse_rect: Invalid height: %f", h); + + m_path.move_to(x, y); + m_path.line_to(x + w, y); + m_path.line_to(x + w, y + h); + m_path.line_to(x, y + h); + m_path.close_subpath(); + } + m_path.end_path(); + } + + + //------------------------------------------------------------- + void parser::parse_line(const char** attr) + { + int i; + double x1 = 0.0; + double y1 = 0.0; + double x2 = 0.0; + double y2 = 0.0; + + m_path.begin_path(); + for(i = 0; attr[i]; i += 2) + { + if(!parse_attr(attr[i], attr[i + 1])) + { + if(strcmp(attr[i], "x1") == 0) x1 = parse_double(attr[i + 1]); + if(strcmp(attr[i], "y1") == 0) y1 = parse_double(attr[i + 1]); + if(strcmp(attr[i], "x2") == 0) x2 = parse_double(attr[i + 1]); + if(strcmp(attr[i], "y2") == 0) y2 = parse_double(attr[i + 1]); + } + } + + m_path.move_to(x1, y1); + m_path.line_to(x2, y2); + m_path.end_path(); + } + + + //------------------------------------------------------------- + void parser::parse_poly(const char** attr, bool close_flag) + { + int i; + double x = 0.0; + double y = 0.0; + + m_path.begin_path(); + for(i = 0; attr[i]; i += 2) + { + if(!parse_attr(attr[i], attr[i + 1])) + { + if(strcmp(attr[i], "points") == 0) + { + m_tokenizer.set_path_str(attr[i + 1]); + if(!m_tokenizer.next()) + { + throw exception("parse_poly: Too few coordinates"); + } + x = m_tokenizer.last_number(); + if(!m_tokenizer.next()) + { + throw exception("parse_poly: Too few coordinates"); + } + y = m_tokenizer.last_number(); + m_path.move_to(x, y); + while(m_tokenizer.next()) + { + x = m_tokenizer.last_number(); + if(!m_tokenizer.next()) + { + throw exception("parse_poly: Odd number of coordinates"); + } + y = m_tokenizer.last_number(); + m_path.line_to(x, y); + } + } + } + } + if(close_flag) + { + m_path.close_subpath(); + } + m_path.end_path(); + } + + //------------------------------------------------------------- + void parser::parse_circle(const char** attr) + { + int i; + double cx = 0.0; + double cy = 0.0; + double r = 0.0; + + m_path.begin_path(); + for(i = 0; attr[i]; i += 2) + { + if(!parse_attr(attr[i], attr[i + 1])) + { + if(strcmp(attr[i], "cx") == 0) cx = parse_double(attr[i + 1]); + if(strcmp(attr[i], "cy") == 0) cy = parse_double(attr[i + 1]); + if(strcmp(attr[i], "r") == 0) r = parse_double(attr[i + 1]); + } + } + + m_path.move_to(cx-r, cy); + m_path.arc(r, r, 360, true, true, 0, .0001, true); + m_path.end_path(); + } + + + void parser::parse_ellipse(const char** attr) + { + int i; + double cx = 0.0; + double cy = 0.0; + double rx = 0.0; + double ry = 0.0; + + m_path.begin_path(); + for(i = 0; attr[i]; i += 2) + { + if(!parse_attr(attr[i], attr[i + 1])) + { + if(strcmp(attr[i], "cx") == 0) cx = parse_double(attr[i + 1]); + if(strcmp(attr[i], "cy") == 0) cy = parse_double(attr[i + 1]); + if(strcmp(attr[i], "rx") == 0) rx = parse_double(attr[i + 1]); + if(strcmp(attr[i], "ry") == 0) ry = parse_double(attr[i + 1]); + } + } + + m_path.move_to(cx-rx, cy); + m_path.arc(rx, ry, 360, true, true, 0, .0001, true); + m_path.end_path(); + } + + + //------------------------------------------------------------- + void parser::parse_transform(const char* str) + { + while(*str) + { + if(islower(*str)) + { + if(strncmp(str, "matrix", 6) == 0) str += parse_matrix(str); else + if(strncmp(str, "translate", 9) == 0) str += parse_translate(str); else + if(strncmp(str, "rotate", 6) == 0) str += parse_rotate(str); else + if(strncmp(str, "scale", 5) == 0) str += parse_scale(str); else + if(strncmp(str, "skewX", 5) == 0) str += parse_skew_x(str); else + if(strncmp(str, "skewY", 5) == 0) str += parse_skew_y(str); else + { + ++str; + } + } + else + { + ++str; + } + } + } + + + //------------------------------------------------------------- + static bool is_numeric(char c) + { + return strchr("0123456789+-.eE", c) != 0; + } + + //------------------------------------------------------------- + static unsigned parse_transform_args(const char* str, + double* args, + unsigned max_na, + unsigned* na) + { + *na = 0; + const char* ptr = str; + while(*ptr && *ptr != '(') ++ptr; + if(*ptr == 0) + { + throw exception("parse_transform_args: Invalid syntax"); + } + const char* end = ptr; + while(*end && *end != ')') ++end; + if(*end == 0) + { + throw exception("parse_transform_args: Invalid syntax"); + } + + while(ptr < end) + { + if(is_numeric(*ptr)) + { + if(*na >= max_na) + { + throw exception("parse_transform_args: Too many arguments"); + } + args[(*na)++] = atof(ptr); + while(ptr < end && is_numeric(*ptr)) ++ptr; + } + else + { + ++ptr; + } + } + return unsigned(end - str); + } + + //------------------------------------------------------------- + unsigned parser::parse_matrix(const char* str) + { + double args[6]; + unsigned na = 0; + unsigned len = parse_transform_args(str, args, 6, &na); + if(na != 6) + { + throw exception("parse_matrix: Invalid number of arguments"); + } + m_path.transform().premultiply(trans_affine(args[0], args[1], args[2], args[3], args[4], args[5])); + return len; + } + + //------------------------------------------------------------- + unsigned parser::parse_translate(const char* str) + { + double args[2]; + unsigned na = 0; + unsigned len = parse_transform_args(str, args, 2, &na); + if(na == 1) args[1] = 0.0; + m_path.transform().premultiply(trans_affine_translation(args[0], args[1])); + return len; + } + + //------------------------------------------------------------- + unsigned parser::parse_rotate(const char* str) + { + double args[3]; + unsigned na = 0; + unsigned len = parse_transform_args(str, args, 3, &na); + if(na == 1) + { + m_path.transform().premultiply(trans_affine_rotation(deg2rad(args[0]))); + } + else if(na == 3) + { + trans_affine t = trans_affine_translation(-args[1], -args[2]); + t *= trans_affine_rotation(deg2rad(args[0])); + t *= trans_affine_translation(args[1], args[2]); + m_path.transform().premultiply(t); + } + else + { + throw exception("parse_rotate: Invalid number of arguments"); + } + return len; + } + + //------------------------------------------------------------- + unsigned parser::parse_scale(const char* str) + { + double args[2]; + unsigned na = 0; + unsigned len = parse_transform_args(str, args, 2, &na); + if(na == 1) args[1] = args[0]; + m_path.transform().premultiply(trans_affine_scaling(args[0], args[1])); + return len; + } + + //------------------------------------------------------------- + unsigned parser::parse_skew_x(const char* str) + { + double arg; + unsigned na = 0; + unsigned len = parse_transform_args(str, &arg, 1, &na); + m_path.transform().premultiply(trans_affine_skewing(deg2rad(arg), 0.0)); + return len; + } + + //------------------------------------------------------------- + unsigned parser::parse_skew_y(const char* str) + { + double arg; + unsigned na = 0; + unsigned len = parse_transform_args(str, &arg, 1, &na); + m_path.transform().premultiply(trans_affine_skewing(0.0, deg2rad(arg))); + return len; + } + +} +} + + diff --git a/examples/svg_viewer/agg_svg_parser.h b/examples/svg_viewer/agg_svg_parser.h new file mode 100644 index 0000000..21df384 --- /dev/null +++ b/examples/svg_viewer/agg_svg_parser.h @@ -0,0 +1,87 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.3 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// SVG parser. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SVG_PARSER_INCLUDED +#define AGG_SVG_PARSER_INCLUDED + +#include "agg_svg_path_tokenizer.h" +#include "agg_svg_path_renderer.h" + +namespace agg +{ +namespace svg +{ + + class parser + { + enum buf_size_e { buf_size = BUFSIZ }; + public: + + ~parser(); + parser(path_renderer& path); + + void parse(const char* fname); + const char* title() const { return m_title; } + + private: + // XML event handlers + static void start_element(void* data, const char* el, const char** attr); + static void end_element(void* data, const char* el); + static void content(void* data, const char* s, int len); + + void parse_attr(const char** attr); + void parse_path(const char** attr); + void parse_poly(const char** attr, bool close_flag); + void parse_circle(const char** attr); + void parse_ellipse(const char** attr); + void parse_rect(const char** attr); + void parse_line(const char** attr); + void parse_style(const char* str); + void parse_transform(const char* str); + + unsigned parse_matrix(const char* str); + unsigned parse_translate(const char* str); + unsigned parse_rotate(const char* str); + unsigned parse_scale(const char* str); + unsigned parse_skew_x(const char* str); + unsigned parse_skew_y(const char* str); + + bool parse_attr(const char* name, const char* value); + bool parse_name_value(const char* nv_start, const char* nv_end); + void copy_name(const char* start, const char* end); + void copy_value(const char* start, const char* end); + + private: + path_renderer& m_path; + path_tokenizer m_tokenizer; + char* m_buf; + char* m_title; + unsigned m_title_len; + bool m_title_flag; + bool m_path_flag; + char* m_attr_name; + char* m_attr_value; + unsigned m_attr_name_len; + unsigned m_attr_value_len; + }; + +} +} + +#endif diff --git a/examples/svg_viewer/agg_svg_path_renderer.cpp b/examples/svg_viewer/agg_svg_path_renderer.cpp new file mode 100644 index 0000000..9eb459a --- /dev/null +++ b/examples/svg_viewer/agg_svg_path_renderer.cpp @@ -0,0 +1,403 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.3 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// Copyright (c) 2008 Rene Rebe <rene@exactcode.de> [arc parser code] +// Copyright (c) 2017 John Horigan <john@glyphic.com> [align_subpath()] +// +// 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 +//---------------------------------------------------------------------------- +// +// SVG path renderer. +// +//---------------------------------------------------------------------------- + +#include <stdio.h> +#include <cmath> +#include "agg_svg_path_renderer.h" + +namespace agg +{ +namespace svg +{ + + //------------------------------------------------------------------------ + path_renderer::path_renderer() : + m_curved(m_storage), + m_curved_count(m_curved), + + m_curved_stroked(m_curved_count), + m_curved_stroked_trans(m_curved_stroked, m_transform), + + m_curved_trans(m_curved_count, m_transform), + m_curved_trans_contour(m_curved_trans) + { + m_curved_trans_contour.auto_detect_orientation(false); + } + + + //------------------------------------------------------------------------ + void path_renderer::remove_all() + { + m_storage.remove_all(); + m_attr_storage.remove_all(); + m_attr_stack.remove_all(); + m_transform.reset(); + } + + //------------------------------------------------------------------------ + void path_renderer::begin_path() + { + push_attr(); + unsigned idx = m_storage.start_new_path(); + m_attr_storage.add(path_attributes(cur_attr(), idx)); + } + + //------------------------------------------------------------------------ + void path_renderer::end_path() + { + if(m_attr_storage.size() == 0) + { + throw exception("end_path : The path was not begun"); + } + path_attributes attr = cur_attr(); + unsigned idx = m_attr_storage[m_attr_storage.size() - 1].index; + attr.index = idx; + m_attr_storage[m_attr_storage.size() - 1] = attr; + pop_attr(); + } + + //------------------------------------------------------------------------ + void path_renderer::move_to(double x, double y, bool rel) // M, m + { + if(rel) m_storage.rel_to_abs(&x, &y); + m_storage.move_to(x, y); + } + + //------------------------------------------------------------------------ + void path_renderer::line_to(double x, double y, bool rel) // L, l + { + if(rel) m_storage.rel_to_abs(&x, &y); + m_storage.line_to(x, y); + } + + //------------------------------------------------------------------------ + void path_renderer::hline_to(double x, bool rel) // H, h + { + double x2 = 0.0; + double y2 = 0.0; + if(m_storage.total_vertices()) + { + m_storage.vertex(m_storage.total_vertices() - 1, &x2, &y2); + if(rel) x += x2; + m_storage.line_to(x, y2); + } + } + + //------------------------------------------------------------------------ + void path_renderer::vline_to(double y, bool rel) // V, v + { + double x2 = 0.0; + double y2 = 0.0; + if(m_storage.total_vertices()) + { + m_storage.vertex(m_storage.total_vertices() - 1, &x2, &y2); + if(rel) y += y2; + m_storage.line_to(x2, y); + } + } + + //------------------------------------------------------------------------ + void path_renderer::curve3(double x1, double y1, // Q, q + double x, double y, bool rel) + { + if(rel) + { + m_storage.rel_to_abs(&x1, &y1); + m_storage.rel_to_abs(&x, &y); + } + m_storage.curve3(x1, y1, x, y); + } + + //------------------------------------------------------------------------ + void path_renderer::curve3(double x, double y, bool rel) // T, t + { + if(rel) + { + m_storage.curve3_rel(x, y); + } else + { + m_storage.curve3(x, y); + } + } + + //------------------------------------------------------------------------ + void path_renderer::curve4(double x1, double y1, // C, c + double x2, double y2, + double x, double y, bool rel) + { + if(rel) + { + m_storage.rel_to_abs(&x1, &y1); + m_storage.rel_to_abs(&x2, &y2); + m_storage.rel_to_abs(&x, &y); + } + m_storage.curve4(x1, y1, x2, y2, x, y); + } + + //------------------------------------------------------------------------ + void path_renderer::curve4(double x2, double y2, // S, s + double x, double y, bool rel) + { + if(rel) + { + m_storage.curve4_rel(x2, y2, x, y); + } else + { + m_storage.curve4(x2, y2, x, y); + } + } + + //------------------------------------------------------------------------ + void path_renderer::arc(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x, double y, bool rel) + { + angle = deg2rad (angle); + if(rel) + { + m_storage.arc_rel(rx, ry, angle, large_arc_flag, sweep_flag, x, y); + } else + { + m_storage.arc_to(rx, ry, angle, large_arc_flag, sweep_flag, x, y); + } + } + + //------------------------------------------------------------------------ + void path_renderer::close_subpath() + { + m_storage.end_poly(path_flags_close); + } + + //------------------------------------------------------------------------ + // If the end points of a subpath are very, very close then make them + // exactly equal so that AGG is not confused. + //------------------------------------------------------------------------ + void path_renderer::align_subpath(unsigned start_idx) + { + m_storage.align_path(start_idx); + } + + //------------------------------------------------------------------------ + path_attributes& path_renderer::cur_attr() + { + if(m_attr_stack.size() == 0) + { + throw exception("cur_attr : Attribute stack is empty"); + } + return m_attr_stack[m_attr_stack.size() - 1]; + } + + //------------------------------------------------------------------------ + void path_renderer::push_attr() + { + m_attr_stack.add(m_attr_stack.size() ? + m_attr_stack[m_attr_stack.size() - 1] : + path_attributes()); + } + + //------------------------------------------------------------------------ + void path_renderer::pop_attr() + { + if(m_attr_stack.size() == 0) + { + throw exception("pop_attr : Attribute stack is empty"); + } + m_attr_stack.remove_last(); + } + + //------------------------------------------------------------------------ + void path_renderer::fill(const rgba8& f) + { + path_attributes& attr = cur_attr(); + attr.fill_color = f; + attr.fill_flag = true; + } + + //------------------------------------------------------------------------ + void path_renderer::stroke(const rgba8& s) + { + path_attributes& attr = cur_attr(); + attr.stroke_color = s; + attr.stroke_flag = true; + } + + //------------------------------------------------------------------------ + void path_renderer::even_odd(bool flag) + { + cur_attr().even_odd_flag = flag; + } + + //------------------------------------------------------------------------ + void path_renderer::stroke_width(double w) + { + cur_attr().stroke_width = w; + } + + //------------------------------------------------------------------------ + void path_renderer::fill_none() + { + cur_attr().fill_flag = false; + } + + //------------------------------------------------------------------------ + void path_renderer::stroke_none() + { + cur_attr().stroke_flag = false; + } + + //------------------------------------------------------------------------ + void path_renderer::fill_opacity(double op) + { + cur_attr().fill_color.opacity(op); + } + + //------------------------------------------------------------------------ + void path_renderer::stroke_opacity(double op) + { + cur_attr().stroke_color.opacity(op); + } + + //------------------------------------------------------------------------ + void path_renderer::line_join(line_join_e join) + { + cur_attr().line_join = join; + } + + //------------------------------------------------------------------------ + void path_renderer::line_cap(line_cap_e cap) + { + cur_attr().line_cap = cap; + } + + //------------------------------------------------------------------------ + void path_renderer::miter_limit(double ml) + { + cur_attr().miter_limit = ml; + } + + //------------------------------------------------------------------------ + trans_affine& path_renderer::transform() + { + return cur_attr().transform; + } + + //------------------------------------------------------------------------ + void path_renderer::parse_path(path_tokenizer& tok) + { + unsigned move_idx = 0; + while(tok.next()) + { + double arg[10]; + char cmd = tok.last_command(); + if (m_storage.total_vertices() == 0 && !(cmd == 'M' || cmd == 'm')) + { + throw exception("path element data attributes must begin with a 'move to'"); + } + unsigned i; + switch(cmd) + { + case 'M': case 'm': + align_subpath(move_idx); + arg[0] = tok.last_number(); + arg[1] = tok.next(cmd); + move_to(arg[0], arg[1], cmd == 'm'); + move_idx = m_storage.total_vertices() - 1; + break; + + case 'L': case 'l': + arg[0] = tok.last_number(); + arg[1] = tok.next(cmd); + line_to(arg[0], arg[1], cmd == 'l'); + break; + + case 'V': case 'v': + vline_to(tok.last_number(), cmd == 'v'); + break; + + case 'H': case 'h': + hline_to(tok.last_number(), cmd == 'h'); + break; + + case 'Q': case 'q': + arg[0] = tok.last_number(); + for(i = 1; i < 4; i++) + { + arg[i] = tok.next(cmd); + } + curve3(arg[0], arg[1], arg[2], arg[3], cmd == 'q'); + break; + + case 'T': case 't': + arg[0] = tok.last_number(); + arg[1] = tok.next(cmd); + curve3(arg[0], arg[1], cmd == 't'); + break; + + case 'C': case 'c': + arg[0] = tok.last_number(); + for(i = 1; i < 6; i++) + { + arg[i] = tok.next(cmd); + } + curve4(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], cmd == 'c'); + break; + + case 'S': case 's': + arg[0] = tok.last_number(); + for(i = 1; i < 4; i++) + { + arg[i] = tok.next(cmd); + } + curve4(arg[0], arg[1], arg[2], arg[3], cmd == 's'); + break; + + case 'A': case 'a': + arg[0] = tok.last_number(); + for(i = 1; i < 7; ++i) + { + arg[i] = tok.next(cmd); + } + arc(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], + cmd == 'a'); + break; + + case 'Z': case 'z': + align_subpath(move_idx); + close_subpath(); + break; + + default: + { + char buf[100]; + sprintf(buf, "parse_path: Invalid Command %c", cmd); + throw exception(buf); + } + } + } + align_subpath(move_idx); + m_storage.start_new_path(); + } + +} +} + diff --git a/examples/svg_viewer/agg_svg_path_renderer.h b/examples/svg_viewer/agg_svg_path_renderer.h new file mode 100644 index 0000000..e3cf6ae --- /dev/null +++ b/examples/svg_viewer/agg_svg_path_renderer.h @@ -0,0 +1,327 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.3 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// Copyright (c) 2008 Rene Rebe <rene@exactcode.de> [arc parser code] +// Copyright (c) 2017 John Horigan <john@glyphic.com> [align_subpath()] +// +// 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 +//---------------------------------------------------------------------------- +// +// SVG path renderer. +// +//---------------------------------------------------------------------------- +#ifndef AGG_SVG_PATH_RENDERER_INCLUDED +#define AGG_SVG_PATH_RENDERER_INCLUDED + +#include "agg_path_storage.h" +#include "agg_conv_transform.h" +#include "agg_conv_stroke.h" +#include "agg_conv_contour.h" +#include "agg_conv_curve.h" +#include "agg_color_rgba.h" +#include "agg_renderer_scanline.h" +#include "agg_bounding_rect.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_svg_path_tokenizer.h" + +namespace agg +{ +namespace svg +{ + template<class VertexSource> class conv_count + { + public: + conv_count(VertexSource& vs) : m_source(&vs), m_count(0) {} + + void count(unsigned n) { m_count = n; } + unsigned count() const { return m_count; } + + void rewind(unsigned path_id) { m_source->rewind(path_id); } + unsigned vertex(double* x, double* y) + { + ++m_count; + return m_source->vertex(x, y); + } + + private: + VertexSource* m_source; + unsigned m_count; + }; + + + + + //============================================================================ + // Basic path attributes + struct path_attributes + { + unsigned index; + rgba8 fill_color; + rgba8 stroke_color; + bool fill_flag; + bool stroke_flag; + bool even_odd_flag; + line_join_e line_join; + line_cap_e line_cap; + double miter_limit; + double stroke_width; + trans_affine transform; + + // Empty constructor + path_attributes() : + index(0), + fill_color(rgba(0,0,0)), + stroke_color(rgba(0,0,0)), + fill_flag(true), + stroke_flag(false), + even_odd_flag(false), + line_join(miter_join), + line_cap(butt_cap), + miter_limit(4.0), + stroke_width(1.0), + transform() + { + } + + // Copy constructor + path_attributes(const path_attributes& attr) : + index(attr.index), + fill_color(attr.fill_color), + stroke_color(attr.stroke_color), + fill_flag(attr.fill_flag), + stroke_flag(attr.stroke_flag), + even_odd_flag(attr.even_odd_flag), + line_join(attr.line_join), + line_cap(attr.line_cap), + miter_limit(attr.miter_limit), + stroke_width(attr.stroke_width), + transform(attr.transform) + { + } + + // Copy constructor with new index value + path_attributes(const path_attributes& attr, unsigned idx) : + index(idx), + fill_color(attr.fill_color), + stroke_color(attr.stroke_color), + fill_flag(attr.fill_flag), + stroke_flag(attr.stroke_flag), + even_odd_flag(attr.even_odd_flag), + line_join(attr.line_join), + line_cap(attr.line_cap), + miter_limit(attr.miter_limit), + stroke_width(attr.stroke_width), + transform(attr.transform) + { + } + }; + + + //============================================================================ + // Path container and renderer. + class path_renderer + { + public: + typedef pod_bvector<path_attributes> attr_storage; + + typedef conv_curve<path_storage> curved; + typedef conv_count<curved> curved_count; + + typedef conv_stroke<curved_count> curved_stroked; + typedef conv_transform<curved_stroked> curved_stroked_trans; + + typedef conv_transform<curved_count> curved_trans; + typedef conv_contour<curved_trans> curved_trans_contour; + + path_renderer(); + + void remove_all(); + + // Use these functions as follows: + // begin_path() when the XML tag <path> comes ("start_element" handler) + // parse_path() on "d=" tag attribute + // end_path() when parsing of the entire tag is done. + void begin_path(); + void parse_path(path_tokenizer& tok); + void end_path(); + + // The following functions are essentially a "reflection" of + // the respective SVG path commands. + void move_to(double x, double y, bool rel=false); // M, m + void line_to(double x, double y, bool rel=false); // L, l + void hline_to(double x, bool rel=false); // H, h + void vline_to(double y, bool rel=false); // V, v + void curve3(double x1, double y1, // Q, q + double x, double y, bool rel=false); + void curve3(double x, double y, bool rel=false); // T, t + void curve4(double x1, double y1, // C, c + double x2, double y2, + double x, double y, bool rel=false); + void curve4(double x2, double y2, // S, s + double x, double y, bool rel=false); + void arc(double rx, double ry, double angle, // A, a + bool large_arc_flag, bool sweep_flag, double x, double y, + bool rel=false); + void close_subpath(); // Z, z + void align_subpath(unsigned start_idx); + +// template<class VertexSource> +// void add_path(VertexSource& vs, +// unsigned path_id = 0, +// bool solid_path = true) +// { +// m_storage.add_path(vs, path_id, solid_path); +// } + + + unsigned vertex_count() const { return m_curved_count.count(); } + + + // Call these functions on <g> tag (start_element, end_element respectively) + void push_attr(); + void pop_attr(); + + // Attribute setting functions. + void fill(const rgba8& f); + void stroke(const rgba8& s); + void even_odd(bool flag); + void stroke_width(double w); + void fill_none(); + void stroke_none(); + void fill_opacity(double op); + void stroke_opacity(double op); + void line_join(line_join_e join); + void line_cap(line_cap_e cap); + void miter_limit(double ml); + trans_affine& transform(); + + // Make all polygons CCW-oriented + void arrange_orientations() + { + m_storage.arrange_orientations_all_paths(path_flags_ccw); + } + + // Expand all polygons + void expand(double value) + { + m_curved_trans_contour.width(value); + } + + unsigned operator [](unsigned idx) + { + m_transform = m_attr_storage[idx].transform; + return m_attr_storage[idx].index; + } + + void bounding_rect(double* x1, double* y1, double* x2, double* y2) + { + agg::conv_transform<agg::path_storage> trans(m_storage, m_transform); + agg::bounding_rect(trans, *this, 0, m_attr_storage.size(), x1, y1, x2, y2); + } + + // Rendering. One can specify two additional parameters: + // trans_affine and opacity. They can be used to transform the whole + // image and/or to make it translucent. + template<class Rasterizer, class Scanline, class Renderer> + void render(Rasterizer& ras, + Scanline& sl, + Renderer& ren, + const trans_affine& mtx, + const rect_i& cb, + double opacity=1.0) + { + unsigned i; + + ras.clip_box(cb.x1, cb.y1, cb.x2, cb.y2); + m_curved_count.count(0); + + for(i = 0; i < m_attr_storage.size(); i++) + { + const path_attributes& attr = m_attr_storage[i]; + m_transform = attr.transform; + m_transform *= mtx; + double scl = m_transform.scale(); + //m_curved.approximation_method(curve_inc); + m_curved.approximation_scale(scl); + m_curved.angle_tolerance(0.0); + + rgba8 color; + + if(attr.fill_flag) + { + ras.reset(); + ras.filling_rule(attr.even_odd_flag ? fill_even_odd : fill_non_zero); + if(fabs(m_curved_trans_contour.width()) < 0.0001) + { + ras.add_path(m_curved_trans, attr.index); + } + else + { + m_curved_trans_contour.miter_limit(attr.miter_limit); + ras.add_path(m_curved_trans_contour, attr.index); + } + + color = attr.fill_color; + color.opacity(color.opacity() * opacity); + ren.color(color); + agg::render_scanlines(ras, sl, ren); + } + + if(attr.stroke_flag) + { + m_curved_stroked.width(attr.stroke_width); + //m_curved_stroked.line_join((attr.line_join == miter_join) ? miter_join_round : attr.line_join); + m_curved_stroked.line_join(attr.line_join); + m_curved_stroked.line_cap(attr.line_cap); + m_curved_stroked.miter_limit(attr.miter_limit); + m_curved_stroked.inner_join(inner_round); + m_curved_stroked.approximation_scale(scl); + + // If the *visual* line width is considerable we + // turn on processing of curve cusps. + //--------------------- + if(attr.stroke_width * scl > 1.0) + { + m_curved.angle_tolerance(0.2); + } + ras.reset(); + ras.filling_rule(fill_non_zero); + ras.add_path(m_curved_stroked_trans, attr.index); + color = attr.stroke_color; + color.opacity(color.opacity() * opacity); + ren.color(color); + agg::render_scanlines(ras, sl, ren); + } + } + } + + private: + path_attributes& cur_attr(); + + path_storage m_storage; + attr_storage m_attr_storage; + attr_storage m_attr_stack; + trans_affine m_transform; + + curved m_curved; + curved_count m_curved_count; + + curved_stroked m_curved_stroked; + curved_stroked_trans m_curved_stroked_trans; + + curved_trans m_curved_trans; + curved_trans_contour m_curved_trans_contour; + }; + +} +} + +#endif diff --git a/examples/svg_viewer/agg_svg_path_tokenizer.cpp b/examples/svg_viewer/agg_svg_path_tokenizer.cpp new file mode 100644 index 0000000..e60516e --- /dev/null +++ b/examples/svg_viewer/agg_svg_path_tokenizer.cpp @@ -0,0 +1,144 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.3 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// SVG path tokenizer. +// +//---------------------------------------------------------------------------- +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include "agg_svg_exception.h" +#include "agg_svg_path_tokenizer.h" + + +namespace agg +{ +namespace svg +{ + + //------------------------------------------------------------------------ + const char path_tokenizer::s_commands[] = "+-MmZzLlHhVvCcSsQqTtAaFfPp"; + const char path_tokenizer::s_numeric[] = ".Ee0123456789"; + const char path_tokenizer::s_separators[] = " ,\t\n\r"; + + //------------------------------------------------------------------------ + path_tokenizer::path_tokenizer() + : m_path(0), m_last_number(0.0), m_last_command(0) + { + init_char_mask(m_commands_mask, s_commands); + init_char_mask(m_numeric_mask, s_numeric); + init_char_mask(m_separators_mask, s_separators); + } + + + //------------------------------------------------------------------------ + void path_tokenizer::set_path_str(const char* str) + { + m_path = str; + m_last_command = 0; + m_last_number = 0.0; + } + + + //------------------------------------------------------------------------ + void path_tokenizer::init_char_mask(char* mask, const char* char_set) + { + memset(mask, 0, 256/8); + while(*char_set) + { + unsigned c = unsigned(*char_set++) & 0xFF; + mask[c >> 3] |= 1 << (c & 7); + } + } + + + //------------------------------------------------------------------------ + bool path_tokenizer::next() + { + if(m_path == 0) return false; + + // Skip all white spaces and other garbage + while(*m_path && !is_command(*m_path) && !is_numeric(*m_path)) + { + if(!is_separator(*m_path)) + { + char buf[100]; + sprintf(buf, "path_tokenizer::next : Invalid Character %c", *m_path); + throw exception(buf); + } + m_path++; + } + + if(*m_path == 0) return false; + + if(is_command(*m_path)) + { + // Check if the command is a numeric sign character + if(*m_path == '-' || *m_path == '+') + { + return parse_number(); + } + m_last_command = *m_path++; + while(*m_path && is_separator(*m_path)) m_path++; + if(*m_path == 0) return true; + } + return parse_number(); + } + + + + //------------------------------------------------------------------------ + double path_tokenizer::next(char cmd) + { + if(!next()) throw exception("parse_path: Unexpected end of path"); + if(last_command() != cmd) + { + char buf[100]; + sprintf(buf, "parse_path: Command %c: bad or missing parameters", cmd); + throw exception(buf); + } + return last_number(); + } + + + //------------------------------------------------------------------------ + bool path_tokenizer::parse_number() + { + char buf[256]; // Should be enough for any number + char* buf_ptr = buf; + + // Copy all sign characters + while(buf_ptr < buf+255 && (*m_path == '-' || *m_path == '+')) + { + *buf_ptr++ = *m_path++; + } + + // Copy all numeric characters + while(buf_ptr < buf+255 && (is_numeric(*m_path))) + { + *buf_ptr++ = *m_path++; + } + *buf_ptr = 0; + m_last_number = atof(buf); + return true; + } + + +} //namespace svg +} //namespace agg + + + + diff --git a/examples/svg_viewer/agg_svg_path_tokenizer.h b/examples/svg_viewer/agg_svg_path_tokenizer.h new file mode 100644 index 0000000..591ec0e --- /dev/null +++ b/examples/svg_viewer/agg_svg_path_tokenizer.h @@ -0,0 +1,114 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.3 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// SVG path tokenizer. +// +//---------------------------------------------------------------------------- +#ifndef AGG_SVG_PATH_TOKENIZER_INCLUDED +#define AGG_SVG_PATH_TOKENIZER_INCLUDED + +#include "agg_svg_exception.h" + +namespace agg +{ +namespace svg +{ + // SVG path tokenizer. + // Example: + // + // agg::svg::path_tokenizer tok; + // + // tok.set_str("M-122.304 84.285L-122.304 84.285 122.203 86.179 "); + // while(tok.next()) + // { + // printf("command='%c' number=%f\n", + // tok.last_command(), + // tok.last_number()); + // } + // + // The tokenizer does all the routine job of parsing the SVG paths. + // It doesn't recognize any graphical primitives, it even doesn't know + // anything about pairs of coordinates (X,Y). The purpose of this class + // is to tokenize the numeric values and commands. SVG paths can + // have single numeric values for Horizontal or Vertical line_to commands + // as well as more than two coordinates (4 or 6) for Bezier curves + // depending on the semantics of the command. + // The behaviour is as follows: + // + // Each call to next() returns true if there's new command or new numeric + // value or false when the path ends. How to interpret the result + // depends on the sematics of the command. For example, command "C" + // (cubic Bezier curve) implies 6 floating point numbers preceded by this + // command. If the command assumes no arguments (like z or Z) the + // the last_number() values won't change, that is, last_number() always + // returns the last recognized numeric value, so does last_command(). + //=============================================================== + class path_tokenizer + { + public: + path_tokenizer(); + + void set_path_str(const char* str); + bool next(); + + double next(char cmd); + + char last_command() const { return m_last_command; } + double last_number() const { return m_last_number; } + + + private: + static void init_char_mask(char* mask, const char* char_set); + + bool contains(const char* mask, unsigned c) const + { + return (mask[(c >> 3) & (256/8-1)] & (1 << (c & 7))) != 0; + } + + bool is_command(unsigned c) const + { + return contains(m_commands_mask, c); + } + + bool is_numeric(unsigned c) const + { + return contains(m_numeric_mask, c); + } + + bool is_separator(unsigned c) const + { + return contains(m_separators_mask, c); + } + + bool parse_number(); + + char m_separators_mask[256/8]; + char m_commands_mask[256/8]; + char m_numeric_mask[256/8]; + + const char* m_path; + double m_last_number; + char m_last_command; + + static const char s_commands[]; + static const char s_numeric[]; + static const char s_separators[]; + }; + +} //namespace svg +} //namespace agg + + +#endif diff --git a/examples/svg_viewer/svg_test.cpp b/examples/svg_viewer/svg_test.cpp new file mode 100644 index 0000000..a70fe16 --- /dev/null +++ b/examples/svg_viewer/svg_test.cpp @@ -0,0 +1,261 @@ +#include <stdio.h> +#include <stdlib.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_pixfmt_rgba.h" +#include "platform/agg_platform_support.h" +#include "ctrl/agg_slider_ctrl.h" +#include "agg_svg_parser.h" + +#define AGG_BGR24 +#include "../pixel_formats.h" + +enum { flip_y = false }; + + +class the_application : public agg::platform_support +{ + agg::svg::path_renderer m_path; + + agg::slider_ctrl<color_type> m_expand; + agg::slider_ctrl<color_type> m_gamma; + agg::slider_ctrl<color_type> m_scale; + agg::slider_ctrl<color_type> m_rotate; + + double m_min_x; + double m_min_y; + double m_max_x; + double m_max_y; + + double m_x; + double m_y; + double m_dx; + double m_dy; + bool m_drag_flag; + +public: + + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_path(), + m_expand(5, 5, 256-5, 11, !flip_y), + m_gamma (5, 5+15, 256-5, 11+15, !flip_y), + m_scale (256+5, 5, 512-5, 11, !flip_y), + m_rotate(256+5, 5+15, 512-5, 11+15, !flip_y), + m_min_x(0.0), + m_min_y(0.0), + m_max_x(0.0), + m_max_y(0.0), + m_x(0.0), + m_y(0.0), + m_dx(0.0), + m_dy(0.0), + m_drag_flag(false) + { + add_ctrl(m_expand); + add_ctrl(m_gamma); + add_ctrl(m_scale); + add_ctrl(m_rotate); + + m_expand.label("Expand=%3.2f"); + m_expand.range(-1, 1.2); + m_expand.value(0.0); + + m_gamma.label("Gamma=%3.2f"); + m_gamma.range(0.0, 3.0); + m_gamma.value(1.0); + + m_scale.label("Scale=%3.2f"); + m_scale.range(0.2, 10.0); + m_scale.value(1.0); + + m_rotate.label("Rotate=%3.2f"); + m_rotate.range(-180.0, 180.0); + m_rotate.value(0.0); + } + + void parse_svg(const char* fname) + { + agg::svg::parser p(m_path); + p.parse(fname); + m_path.bounding_rect(&m_min_x, &m_min_y, &m_max_x, &m_max_y); + caption(p.title()); + } + + virtual void on_resize(int cx, int cy) + { + } + + virtual void on_draw() + { + typedef agg::pixfmt_bgra32 pixfmt; + 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 ren(rb); + + rb.clear(agg::rgba(1,1,1)); + + agg::rasterizer_scanline_aa<> ras; + agg::scanline_p8 sl; + agg::trans_affine mtx; + + ras.gamma(agg::gamma_power(m_gamma.value())); + mtx *= agg::trans_affine_translation((m_min_x + m_max_x) * -0.5, (m_min_y + m_max_y) * -0.5); + mtx *= agg::trans_affine_scaling(m_scale.value()); + mtx *= agg::trans_affine_rotation(agg::deg2rad(m_rotate.value())); + mtx *= agg::trans_affine_translation((m_min_x + m_max_x) * 0.5 + m_x, (m_min_y + m_max_y) * 0.5 + m_y + 30); + + m_path.expand(m_expand.value()); + start_timer(); + m_path.render(ras, sl, ren, mtx, rb.clip_box(), 1.0); + double tm = elapsed_time(); + unsigned vertex_count = m_path.vertex_count(); + + ras.gamma(agg::gamma_none()); + agg::render_ctrl(ras, sl, rb, m_expand); + agg::render_ctrl(ras, sl, rb, m_gamma); + agg::render_ctrl(ras, sl, rb, m_scale); + agg::render_ctrl(ras, sl, rb, m_rotate); + + + char buf[128]; + agg::gsv_text t; + t.size(10.0); + t.flip(true); + + agg::conv_stroke<agg::gsv_text> pt(t); + pt.width(1.5); + + sprintf(buf, "Vertices=%d Time=%.3f ms", vertex_count, tm); + + t.start_point(10.0, 40.0); + t.text(buf); + + ras.add_path(pt); + ren.color(agg::rgba(0,0,0)); + agg::render_scanlines(ras, sl, ren); + + + //agg::gamma_lut<> gl(m_gamma.value()); + //unsigned x, y; + //unsigned w = unsigned(width()); + //unsigned h = unsigned(height()); + //for(y = 0; y < h; y++) + //{ + // for(x = 0; x < w; x++) + // { + // agg::rgba8 c = rb.pixel(x, y); + // c.r = gl.inv(c.r); + // c.g = gl.inv(c.g); + // c.b = gl.inv(c.b); + // rb.copy_pixel(x, y, c); + // } + //} + } + + virtual void on_mouse_button_down(int x, int y, unsigned flags) + { + m_dx = x - m_x; + m_dy = y - m_y; + m_drag_flag = true; + } + + virtual void on_mouse_move(int x, int y, unsigned flags) + { + if(flags == 0) + { + m_drag_flag = false; + } + + if(m_drag_flag) + { + m_x = x - m_dx; + m_y = y - m_dy; + force_redraw(); + } + } + + virtual void on_mouse_button_up(int x, int y, unsigned flags) + { + m_drag_flag = false; + } + + virtual void on_key(int x, int y, unsigned key, unsigned flags) + { + if(key == ' ') + { + + agg::trans_affine mtx; + mtx *= agg::trans_affine_translation((m_min_x + m_max_x) * -0.5, (m_min_y + m_max_y) * -0.5); + mtx *= agg::trans_affine_scaling(m_scale.value()); + mtx *= agg::trans_affine_rotation(agg::deg2rad(m_rotate.value())); + mtx *= agg::trans_affine_translation((m_min_x + m_max_x) * 0.5, (m_min_y + m_max_y) * 0.5); + mtx *= agg::trans_affine_translation(m_x, m_y); + + double m[6]; + mtx.store_to(m); + + char buf[128]; + sprintf(buf, "%3.3f, %3.3f, %3.3f, %3.3f, %3.3f, %3.3f", + m[0], m[1], m[2], m[3], m[4], m[5]); + + message(buf); + FILE* fd = fopen(full_file_name("transform.txt"), "a"); + fprintf(fd, "%s\n", buf); + fclose(fd); + } + } + + + +}; + + + + +int agg_main(int argc, char* argv[]) +{ + the_application app(agg::pix_format_bgra32, flip_y); + + const char* fname = "tiger.svg"; + if(argc <= 1) + { + FILE* fd = fopen(app.full_file_name(fname), "r"); + if(fd == 0) + { + app.message("Usage: svg_test <svg_file>\n" + "Copy ../art/tiger.svg"); + return 1; + } + fclose(fd); + } + else + { + fname = argv[1]; + } + + try + { + app.parse_svg(app.full_file_name(fname)); + } + catch(agg::svg::exception& e) + { + app.message(e.msg()); + return 1; + } + + if(app.init(512, 600, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + + diff --git a/examples/trans_curve1.cpp b/examples/trans_curve1.cpp new file mode 100644 index 0000000..b103686 --- /dev/null +++ b/examples/trans_curve1.cpp @@ -0,0 +1,327 @@ +#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 "agg_conv_segmentator.h" +#include "agg_font_win32_tt.h" +#include "agg_trans_single_path.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_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 }; + + + + +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. "; + + + + +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::scanline_p8 scanline_type; + typedef agg::font_engine_win32_tt_int16 font_engine_type; + typedef agg::font_cache_manager<font_engine_type> font_manager_type; + + font_engine_type m_feng; + font_manager_type m_fman; + agg::interactive_polygon m_poly; + agg::slider_ctrl<color_type> m_num_points; + agg::cbox_ctrl<color_type> m_close; + agg::cbox_ctrl<color_type> m_preserve_x_scale; + agg::cbox_ctrl<color_type> m_fixed_len; + agg::cbox_ctrl<color_type> m_animate; + double m_dx[6]; + double m_dy[6]; + bool m_prev_animate; + + the_application(HDC dc, agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_feng(dc), + m_fman(m_feng), + 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_preserve_x_scale(460, 5.0, "Preserve X scale", !flip_y), + m_fixed_len (350, 25.0, "Fixed Length", !flip_y), + m_animate (460, 25.0, "Animate", !flip_y), + m_prev_animate(false) + { + add_ctrl(m_close); + add_ctrl(m_preserve_x_scale); + add_ctrl(m_fixed_len); + add_ctrl(m_animate); + m_preserve_x_scale.status(true); + m_fixed_len.status(true); + m_num_points.range(10.0, 400.0); + m_num_points.value(200.0); + m_num_points.label("Number of intermediate Points = %.3f"); + add_ctrl(m_num_points); + } + + + virtual void on_init() + { + m_poly.xn(0) = 50; + m_poly.yn(0) = 50; + m_poly.xn(1) = 150 + 20; + m_poly.yn(1) = 150 - 20; + m_poly.xn(2) = 250 - 20; + m_poly.yn(2) = 250 + 20; + m_poly.xn(3) = 350 + 20; + m_poly.yn(3) = 350 - 20; + m_poly.xn(4) = 450 - 20; + m_poly.yn(4) = 450 + 20; + m_poly.xn(5) = 550; + m_poly.yn(5) = 550; + } + + + + + virtual void on_draw() + { + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_solid r(rb); + rb.clear(agg::rgba(1, 1, 1)); + + scanline_type sl; + agg::rasterizer_scanline_aa<> ras; + + m_poly.close(m_close.status()); + 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()); + + agg::trans_single_path tcurve; + tcurve.add_path(bspline); + tcurve.preserve_x_scale(m_preserve_x_scale.status()); + if(m_fixed_len.status()) tcurve.base_length(1120); + + typedef agg::conv_curve<font_manager_type::path_adaptor_type> conv_font_curve_type; + typedef agg::conv_segmentator<conv_font_curve_type> conv_font_segm_type; + typedef agg::conv_transform<conv_font_segm_type, agg::trans_single_path> conv_font_trans_type; + conv_font_curve_type fcurves(m_fman.path_adaptor()); + + conv_font_segm_type fsegm(fcurves); + conv_font_trans_type ftrans(fsegm, tcurve); + fsegm.approximation_scale(3.0); + fcurves.approximation_scale(2.0); + + m_feng.height(40.0); + //m_feng.italic(true); + + if(m_feng.create_font("Times New Roman", agg::glyph_ren_outline)) + { + double x = 0.0; + double y = 3.0; + const char* p = text; + + while(*p) + { + const agg::glyph_cache* glyph = m_fman.glyph(*p); + if(glyph) + { + if(x > tcurve.total_length()) break; + + m_fman.add_kerning(&x, &y); + m_fman.init_embedded_adaptors(glyph, x, y); + + if(glyph->data_type == agg::glyph_data_outline) + { + ras.reset(); + ras.add_path(ftrans); + r.color(agg::srgba8(0, 0, 0)); + agg::render_scanlines(ras, sl, r); + } + + // increment pen position + x += glyph->advance_x; + y += glyph->advance_y; + } + ++p; + } + + } + + + + typedef agg::conv_stroke<conv_bspline_type> conv_stroke_type; + conv_stroke_type stroke(bspline); + + stroke.width(2.0); + + r.color(agg::srgba8(170, 50, 20, 100)); + ras.add_path(stroke); + agg::render_scanlines(ras, sl, r); + + //-------------------------- + // Render the "poly" tool and controls + r.color(agg::rgba(0, 0.3, 0.5, 0.3)); + ras.add_path(m_poly); + agg::render_scanlines(ras, sl, r); + + agg::render_ctrl(ras, sl, rb, m_close); + agg::render_ctrl(ras, sl, rb, m_preserve_x_scale); + agg::render_ctrl(ras, sl, rb, m_fixed_len); + agg::render_ctrl(ras, sl, rb, m_animate); + 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) + { + } + + + virtual void on_ctrl_change() + { + if(m_animate.status() != m_prev_animate) + { + if(m_animate.status()) + { + on_init(); + int i; + for(i = 0; i < 6; i++) + { + m_dx[i] = ((rand() % 1000) - 500) * 0.01; + m_dy[i] = ((rand() % 1000) - 500) * 0.01; + } + wait_mode(false); + } + else + { + wait_mode(true); + } + m_prev_animate = m_animate.status(); + } + } + + + void move_point(double& x, double& y, double& dx, double& dy) + { + if(x < 0.0) { x = 0.0; dx = -dx; } + if(x > width()) { x = width(); dx = -dx; } + if(y < 0.0) { y = 0.0; dy = -dy; } + if(y > height()) { y = height(); dy = -dy; } + x += dx; + y += dy; + } + + + + virtual void on_idle() + { + int i; + for(i = 0; i < 6; i++) + { + move_point(m_poly.xn(i), m_poly.yn(i), m_dx[i], m_dy[i]); + } + force_redraw(); + } + + +}; + + + + + + +int agg_main(int argc, char* argv[]) +{ + HDC dc = ::GetDC(0); + the_application app(dc, pix_format, flip_y); + app.caption("AGG Example. Non-linear \"Along-A-Curve\" Transformer"); + + if(app.init(600, 600, agg::window_resize)) + { + return app.run(); + } + ::ReleaseDC(0, dc); + return 1; +} + + + + + + + + + + diff --git a/examples/trans_curve1_ft.cpp b/examples/trans_curve1_ft.cpp new file mode 100644 index 0000000..490f2d9 --- /dev/null +++ b/examples/trans_curve1_ft.cpp @@ -0,0 +1,327 @@ +#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 "agg_conv_segmentator.h" +#include "agg_font_freetype.h" +#include "agg_trans_single_path.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_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 }; + + + + +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. "; + + + + +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::scanline_p8 scanline_type; + typedef agg::font_engine_freetype_int16 font_engine_type; + typedef agg::font_cache_manager<font_engine_type> font_manager_type; + + font_engine_type m_feng; + font_manager_type m_fman; + agg::interactive_polygon m_poly; + agg::slider_ctrl<color_type> m_num_points; + agg::cbox_ctrl<color_type> m_close; + agg::cbox_ctrl<color_type> m_preserve_x_scale; + agg::cbox_ctrl<color_type> m_fixed_len; + agg::cbox_ctrl<color_type> m_animate; + double m_dx[6]; + double m_dy[6]; + bool m_prev_animate; + + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_feng(), + m_fman(m_feng), + 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_preserve_x_scale(460, 5.0, "Preserve X scale", !flip_y), + m_fixed_len (350, 25.0, "Fixed Length", !flip_y), + m_animate (460, 25.0, "Animate", !flip_y), + m_prev_animate(false) + { + add_ctrl(m_close); + add_ctrl(m_preserve_x_scale); + add_ctrl(m_fixed_len); + add_ctrl(m_animate); + m_preserve_x_scale.status(true); + m_fixed_len.status(true); + m_num_points.range(10.0, 400.0); + m_num_points.value(200.0); + m_num_points.label("Number of intermediate Points = %.3f"); + add_ctrl(m_num_points); + } + + + virtual void on_init() + { + m_poly.xn(0) = 50; + m_poly.yn(0) = 50; + m_poly.xn(1) = 150 + 20; + m_poly.yn(1) = 150 - 20; + m_poly.xn(2) = 250 - 20; + m_poly.yn(2) = 250 + 20; + m_poly.xn(3) = 350 + 20; + m_poly.yn(3) = 350 - 20; + m_poly.xn(4) = 450 - 20; + m_poly.yn(4) = 450 + 20; + m_poly.xn(5) = 550; + m_poly.yn(5) = 550; + } + + + + + virtual void on_draw() + { + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_solid r(rb); + rb.clear(agg::rgba(1, 1, 1)); + + scanline_type sl; + agg::rasterizer_scanline_aa<> ras; + + m_poly.close(m_close.status()); + 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()); + + agg::trans_single_path tcurve; + tcurve.add_path(bspline); + tcurve.preserve_x_scale(m_preserve_x_scale.status()); + if(m_fixed_len.status()) tcurve.base_length(1120); + + typedef agg::conv_curve<font_manager_type::path_adaptor_type> conv_font_curve_type; + typedef agg::conv_segmentator<conv_font_curve_type> conv_font_segm_type; + typedef agg::conv_transform<conv_font_segm_type, agg::trans_single_path> conv_font_trans_type; + conv_font_curve_type fcurves(m_fman.path_adaptor()); + + conv_font_segm_type fsegm(fcurves); + conv_font_trans_type ftrans(fsegm, tcurve); + fsegm.approximation_scale(3.0); + fcurves.approximation_scale(2.0); + + if(m_feng.load_font(full_file_name("timesi.ttf"), 0, agg::glyph_ren_outline)) + { + double x = 0.0; + double y = 3.0; + const char* p = text; + + m_feng.hinting(false); + m_feng.height(40); + + while(*p) + { + const agg::glyph_cache* glyph = m_fman.glyph(*p); + if(glyph) + { + if(x > tcurve.total_length()) break; + + m_fman.add_kerning(&x, &y); + m_fman.init_embedded_adaptors(glyph, x, y); + + if(glyph->data_type == agg::glyph_data_outline) + { + ras.reset(); + ras.add_path(ftrans); + r.color(agg::srgba8(0, 0, 0)); + agg::render_scanlines(ras, sl, r); + } + + // increment pen position + x += glyph->advance_x; + y += glyph->advance_y; + } + ++p; + } + } + else + { + message("Please copy file timesi.ttf to the current directory\n" + "or unzip it from ../art/timesi.zip"); + } + + + + typedef agg::conv_stroke<conv_bspline_type> conv_stroke_type; + conv_stroke_type stroke(bspline); + + stroke.width(2.0); + + r.color(agg::srgba8(170, 50, 20, 100)); + ras.add_path(stroke); + agg::render_scanlines(ras, sl, r); + + //-------------------------- + // Render the "poly" tool and controls + r.color(agg::rgba(0, 0.3, 0.5, 0.3)); + ras.add_path(m_poly); + agg::render_scanlines(ras, sl, r); + + agg::render_ctrl(ras, sl, rb, m_close); + agg::render_ctrl(ras, sl, rb, m_preserve_x_scale); + agg::render_ctrl(ras, sl, rb, m_fixed_len); + agg::render_ctrl(ras, sl, rb, m_animate); + 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) + { + } + + + virtual void on_ctrl_change() + { + if(m_animate.status() != m_prev_animate) + { + if(m_animate.status()) + { + on_init(); + int i; + for(i = 0; i < 6; i++) + { + m_dx[i] = ((rand() % 1000) - 500) * 0.01; + m_dy[i] = ((rand() % 1000) - 500) * 0.01; + } + wait_mode(false); + } + else + { + wait_mode(true); + } + m_prev_animate = m_animate.status(); + } + } + + + void move_point(double& x, double& y, double& dx, double& dy) + { + if(x < 0.0) { x = 0.0; dx = -dx; } + if(x > width()) { x = width(); dx = -dx; } + if(y < 0.0) { y = 0.0; dy = -dy; } + if(y > height()) { y = height(); dy = -dy; } + x += dx; + y += dy; + } + + + + virtual void on_idle() + { + int i; + for(i = 0; i < 6; i++) + { + move_point(m_poly.xn(i), m_poly.yn(i), m_dx[i], m_dy[i]); + } + force_redraw(); + } + + +}; + + + + + + +int agg_main(int argc, char* argv[]) +{ + the_application app(pix_format, flip_y); + app.caption("AGG Example. Non-linear \"Along-A-Curve\" Transformer"); + + if(app.init(600, 600, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + + + + + + + + + diff --git a/examples/trans_curve2.cpp b/examples/trans_curve2.cpp new file mode 100644 index 0000000..3aec247 --- /dev/null +++ b/examples/trans_curve2.cpp @@ -0,0 +1,394 @@ +#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 "agg_conv_segmentator.h" +#include "agg_font_win32_tt.h" +#include "agg_trans_double_path.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_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 }; + + + + +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. "; + + + + +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::scanline_p8 scanline_type; + typedef agg::font_engine_win32_tt_int16 font_engine_type; + typedef agg::font_cache_manager<font_engine_type> font_manager_type; + + font_engine_type m_feng; + font_manager_type m_fman; + agg::interactive_polygon m_poly1; + agg::interactive_polygon m_poly2; + agg::slider_ctrl<color_type> m_num_points; + agg::cbox_ctrl<color_type> m_fixed_len; + agg::cbox_ctrl<color_type> m_preserve_x_scale; + agg::cbox_ctrl<color_type> m_animate; + double m_dx1[6]; + double m_dy1[6]; + double m_dx2[6]; + double m_dy2[6]; + bool m_prev_animate; + + the_application(HDC dc, agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_feng(dc), + m_fman(m_feng), + m_poly1(6, 5.0), + m_poly2(6, 5.0), + m_num_points (5.0, 5.0, 340.0, 12.0, !flip_y), + m_fixed_len (350, 5.0, "Fixed Length", !flip_y), + m_preserve_x_scale(465, 5.0, "Preserve X scale", !flip_y), + m_animate (350, 25.0, "Animate", !flip_y), + m_prev_animate(false) + { + add_ctrl(m_fixed_len); + add_ctrl(m_preserve_x_scale); + add_ctrl(m_animate); + m_fixed_len.status(true); + m_preserve_x_scale.status(true); + m_num_points.range(10.0, 400.0); + m_num_points.value(200.0); + m_num_points.label("Number of intermediate Points = %.3f"); + add_ctrl(m_num_points); + + m_poly1.close(false); + m_poly2.close(false); + } + + + virtual void on_init() + { + m_poly1.xn(0) = 10 + 50; + m_poly1.yn(0) = -10 + 50; + m_poly1.xn(1) = 10 + 150 + 20; + m_poly1.yn(1) = -10 + 150 - 20; + m_poly1.xn(2) = 10 + 250 - 20; + m_poly1.yn(2) = -10 + 250 + 20; + m_poly1.xn(3) = 10 + 350 + 20; + m_poly1.yn(3) = -10 + 350 - 20; + m_poly1.xn(4) = 10 + 450 - 20; + m_poly1.yn(4) = -10 + 450 + 20; + m_poly1.xn(5) = 10 + 550; + m_poly1.yn(5) = -10 + 550; + + m_poly2.xn(0) = -10 + 50; + m_poly2.yn(0) = 10 + 50; + m_poly2.xn(1) = -10 + 150 + 20; + m_poly2.yn(1) = 10 + 150 - 20; + m_poly2.xn(2) = -10 + 250 - 20; + m_poly2.yn(2) = 10 + 250 + 20; + m_poly2.xn(3) = -10 + 350 + 20; + m_poly2.yn(3) = 10 + 350 - 20; + m_poly2.xn(4) = -10 + 450 - 20; + m_poly2.yn(4) = 10 + 450 + 20; + m_poly2.xn(5) = -10 + 550; + m_poly2.yn(5) = 10 + 550; + } + + + + + virtual void on_draw() + { + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_solid r(rb); + rb.clear(agg::rgba(1, 1, 1)); + + scanline_type sl; + agg::rasterizer_scanline_aa<> ras; + + agg::simple_polygon_vertex_source path1(m_poly1.polygon(), + m_poly1.num_points(), + false, + false); + + agg::simple_polygon_vertex_source path2(m_poly2.polygon(), + m_poly2.num_points(), + false, + false); + + + typedef agg::conv_bspline<agg::simple_polygon_vertex_source> conv_bspline_type; + conv_bspline_type bspline1(path1); + conv_bspline_type bspline2(path2); + bspline1.interpolation_step(1.0 / m_num_points.value()); + bspline2.interpolation_step(1.0 / m_num_points.value()); + + + typedef agg::conv_curve<font_manager_type::path_adaptor_type> conv_font_curve_type; + typedef agg::conv_segmentator<conv_font_curve_type> conv_font_segm_type; + typedef agg::conv_transform<conv_font_segm_type, agg::trans_double_path> conv_font_trans_type; + + agg::trans_double_path tcurve; + conv_font_curve_type fcurves(m_fman.path_adaptor()); + conv_font_segm_type fsegm(fcurves); + conv_font_trans_type ftrans(fsegm, tcurve); + + tcurve.preserve_x_scale(m_preserve_x_scale.status()); + if(m_fixed_len.status()) tcurve.base_length(1140.0); + tcurve.base_height(30.0); + + tcurve.add_paths(bspline1, bspline2); + fsegm.approximation_scale(3.0); + fcurves.approximation_scale(5.0); + + + + m_feng.height(40.0); + m_feng.hinting(false); + m_feng.italic(true); + + if(m_feng.create_font("Times New Roman", agg::glyph_ren_outline)) + { + double x = 0.0; + double y = 3.0; + const char* p = text; + + while(*p) + { + const agg::glyph_cache* glyph = m_fman.glyph(*p); + if(glyph) + { + if(x > tcurve.total_length1()) break; + + m_fman.add_kerning(&x, &y); + m_fman.init_embedded_adaptors(glyph, x, y); + + if(glyph->data_type == agg::glyph_data_outline) + { + ras.reset(); + ras.add_path(ftrans); + r.color(agg::srgba8(0, 0, 0)); + agg::render_scanlines(ras, sl, r); + } + + // increment pen position + x += glyph->advance_x; + y += glyph->advance_y; + } + ++p; + } + + } + + + + typedef agg::conv_stroke<conv_bspline_type> conv_stroke_type; + conv_stroke_type stroke1(bspline1); + conv_stroke_type stroke2(bspline2); + + stroke1.width(2.0); + stroke2.width(2.0); + + r.color(agg::srgba8(170, 50, 20, 100)); + ras.add_path(stroke1); + agg::render_scanlines(ras, sl, r); + + ras.add_path(stroke2); + agg::render_scanlines(ras, sl, r); + + + //-------------------------- + // Render the "poly" tool and controls + r.color(agg::rgba(0, 0.3, 0.5, 0.2)); + ras.add_path(m_poly1); + agg::render_scanlines(ras, sl, r); + + ras.add_path(m_poly2); + agg::render_scanlines(ras, sl, r); + + + agg::render_ctrl(ras, sl, rb, m_fixed_len); + agg::render_ctrl(ras, sl, rb, m_preserve_x_scale); + agg::render_ctrl(ras, sl, rb, m_animate); + 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_poly1.on_mouse_button_down(x, y)) + { + force_redraw(); + } + if(m_poly2.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_poly1.on_mouse_move(x, y)) + { + force_redraw(); + } + if(m_poly2.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_poly1.on_mouse_button_up(x, y)) + { + force_redraw(); + } + if(m_poly2.on_mouse_button_up(x, y)) + { + force_redraw(); + } + } + + + virtual void on_key(int x, int y, unsigned key, unsigned flags) + { + } + + + virtual void on_ctrl_change() + { + if(m_animate.status() != m_prev_animate) + { + if(m_animate.status()) + { + on_init(); + int i; + for(i = 0; i < 6; i++) + { + m_dx1[i] = ((rand() % 1000) - 500) * 0.01; + m_dy1[i] = ((rand() % 1000) - 500) * 0.01; + m_dx2[i] = ((rand() % 1000) - 500) * 0.01; + m_dy2[i] = ((rand() % 1000) - 500) * 0.01; + } + wait_mode(false); + } + else + { + wait_mode(true); + } + m_prev_animate = m_animate.status(); + } + } + + + void move_point(double& x, double& y, double& dx, double& dy) + { + if(x < 0.0) { x = 0.0; dx = -dx; } + if(x > width()) { x = width(); dx = -dx; } + if(y < 0.0) { y = 0.0; dy = -dy; } + if(y > height()) { y = height(); dy = -dy; } + x += dx; + y += dy; + } + + + void normalize_point(unsigned i) + { + double d = agg::calc_distance(m_poly1.xn(i), m_poly1.yn(i), + m_poly2.xn(i), m_poly2.yn(i)); + // 28.8 is 20 * sqrt(2) + if(d > 28.28) + { + m_poly2.xn(i) = m_poly1.xn(i) + (m_poly2.xn(i) - m_poly1.xn(i)) * 28.28 / d; + m_poly2.yn(i) = m_poly1.yn(i) + (m_poly2.yn(i) - m_poly1.yn(i)) * 28.28 / d; + } + } + + + + virtual void on_idle() + { + int i; + for(i = 0; i < 6; i++) + { + move_point(m_poly1.xn(i), m_poly1.yn(i), m_dx1[i], m_dy1[i]); + move_point(m_poly2.xn(i), m_poly2.yn(i), m_dx2[i], m_dy2[i]); + normalize_point(i); + } + force_redraw(); + } + +}; + + + + + + +int agg_main(int argc, char* argv[]) +{ + HDC dc = ::GetDC(0); + the_application app(dc, pix_format, flip_y); + app.caption("AGG Example. Non-linear \"Along-A-Curve\" Transformer"); + + if(app.init(600, 600, agg::window_resize)) + { + return app.run(); + } + ::ReleaseDC(0, dc); + return 1; +} + + + + + + + + + + diff --git a/examples/trans_curve2_ft.cpp b/examples/trans_curve2_ft.cpp new file mode 100644 index 0000000..1e207cd --- /dev/null +++ b/examples/trans_curve2_ft.cpp @@ -0,0 +1,391 @@ +#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 "agg_conv_segmentator.h" +#include "agg_font_freetype.h" +#include "agg_trans_double_path.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_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 }; + + + + +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. "; + + + + +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::scanline_p8 scanline_type; + typedef agg::font_engine_freetype_int16 font_engine_type; + typedef agg::font_cache_manager<font_engine_type> font_manager_type; + + font_engine_type m_feng; + font_manager_type m_fman; + agg::interactive_polygon m_poly1; + agg::interactive_polygon m_poly2; + agg::slider_ctrl<color_type> m_num_points; + agg::cbox_ctrl<color_type> m_fixed_len; + agg::cbox_ctrl<color_type> m_preserve_x_scale; + agg::cbox_ctrl<color_type> m_animate; + double m_dx1[6]; + double m_dy1[6]; + double m_dx2[6]; + double m_dy2[6]; + bool m_prev_animate; + + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_feng(), + m_fman(m_feng), + m_poly1(6, 5.0), + m_poly2(6, 5.0), + m_num_points (5.0, 5.0, 340.0, 12.0, !flip_y), + m_fixed_len (350, 5.0, "Fixed Length", !flip_y), + m_preserve_x_scale(465, 5.0, "Preserve X scale", !flip_y), + m_animate (350, 25.0, "Animate", !flip_y), + m_prev_animate(false) + { + add_ctrl(m_fixed_len); + add_ctrl(m_preserve_x_scale); + add_ctrl(m_animate); + m_fixed_len.status(true); + m_preserve_x_scale.status(true); + m_num_points.range(10.0, 400.0); + m_num_points.value(200.0); + m_num_points.label("Number of intermediate Points = %.3f"); + add_ctrl(m_num_points); + + m_poly1.close(false); + m_poly2.close(false); + } + + + virtual void on_init() + { + m_poly1.xn(0) = 10 + 50; + m_poly1.yn(0) = -10 + 50; + m_poly1.xn(1) = 10 + 150 + 20; + m_poly1.yn(1) = -10 + 150 - 20; + m_poly1.xn(2) = 10 + 250 - 20; + m_poly1.yn(2) = -10 + 250 + 20; + m_poly1.xn(3) = 10 + 350 + 20; + m_poly1.yn(3) = -10 + 350 - 20; + m_poly1.xn(4) = 10 + 450 - 20; + m_poly1.yn(4) = -10 + 450 + 20; + m_poly1.xn(5) = 10 + 550; + m_poly1.yn(5) = -10 + 550; + + m_poly2.xn(0) = -10 + 50; + m_poly2.yn(0) = 10 + 50; + m_poly2.xn(1) = -10 + 150 + 20; + m_poly2.yn(1) = 10 + 150 - 20; + m_poly2.xn(2) = -10 + 250 - 20; + m_poly2.yn(2) = 10 + 250 + 20; + m_poly2.xn(3) = -10 + 350 + 20; + m_poly2.yn(3) = 10 + 350 - 20; + m_poly2.xn(4) = -10 + 450 - 20; + m_poly2.yn(4) = 10 + 450 + 20; + m_poly2.xn(5) = -10 + 550; + m_poly2.yn(5) = 10 + 550; + } + + + + + virtual void on_draw() + { + pixfmt pixf(rbuf_window()); + renderer_base rb(pixf); + renderer_solid r(rb); + rb.clear(agg::rgba(1, 1, 1)); + + scanline_type sl; + agg::rasterizer_scanline_aa<> ras; + + agg::simple_polygon_vertex_source path1(m_poly1.polygon(), + m_poly1.num_points(), + false, + false); + + agg::simple_polygon_vertex_source path2(m_poly2.polygon(), + m_poly2.num_points(), + false, + false); + + + typedef agg::conv_bspline<agg::simple_polygon_vertex_source> conv_bspline_type; + conv_bspline_type bspline1(path1); + conv_bspline_type bspline2(path2); + bspline1.interpolation_step(1.0 / m_num_points.value()); + bspline2.interpolation_step(1.0 / m_num_points.value()); + + + typedef agg::conv_curve<font_manager_type::path_adaptor_type> conv_font_curve_type; + typedef agg::conv_segmentator<conv_font_curve_type> conv_font_segm_type; + typedef agg::conv_transform<conv_font_segm_type, agg::trans_double_path> conv_font_trans_type; + + agg::trans_double_path tcurve; + conv_font_curve_type fcurves(m_fman.path_adaptor()); + conv_font_segm_type fsegm(fcurves); + conv_font_trans_type ftrans(fsegm, tcurve); + + tcurve.preserve_x_scale(m_preserve_x_scale.status()); + if(m_fixed_len.status()) tcurve.base_length(1140.0); + tcurve.base_height(30.0); + + tcurve.add_paths(bspline1, bspline2); + fsegm.approximation_scale(3.0); + fcurves.approximation_scale(5.0); + + if(m_feng.load_font(full_file_name("timesi.ttf"), 0, agg::glyph_ren_outline)) + { + double x = 0.0; + double y = 3.0; + const char* p = text; + + m_feng.hinting(false); + m_feng.height(40); + + while(*p) + { + const agg::glyph_cache* glyph = m_fman.glyph(*p); + if(glyph) + { + if(x > tcurve.total_length1()) break; + + m_fman.add_kerning(&x, &y); + m_fman.init_embedded_adaptors(glyph, x, y); + + if(glyph->data_type == agg::glyph_data_outline) + { + ras.reset(); + ras.add_path(ftrans); + r.color(agg::srgba8(0, 0, 0)); + agg::render_scanlines(ras, sl, r); + } + + // increment pen position + x += glyph->advance_x; + y += glyph->advance_y; + } + ++p; + } + } + else + { + message("Please copy file timesi.ttf to the current directory\n" + "or unzip it from ../art/timesi.zip"); + } + + + + typedef agg::conv_stroke<conv_bspline_type> conv_stroke_type; + conv_stroke_type stroke1(bspline1); + conv_stroke_type stroke2(bspline2); + + stroke1.width(2.0); + stroke2.width(2.0); + + r.color(agg::srgba8(170, 50, 20, 100)); + ras.add_path(stroke1); + agg::render_scanlines(ras, sl, r); + + ras.add_path(stroke2); + agg::render_scanlines(ras, sl, r); + + + //-------------------------- + // Render the "poly" tool and controls + r.color(agg::rgba(0, 0.3, 0.5, 0.2)); + ras.add_path(m_poly1); + agg::render_scanlines(ras, sl, r); + + ras.add_path(m_poly2); + agg::render_scanlines(ras, sl, r); + + + agg::render_ctrl(ras, sl, rb, m_fixed_len); + agg::render_ctrl(ras, sl, rb, m_preserve_x_scale); + agg::render_ctrl(ras, sl, rb, m_animate); + 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_poly1.on_mouse_button_down(x, y)) + { + force_redraw(); + } + if(m_poly2.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_poly1.on_mouse_move(x, y)) + { + force_redraw(); + } + if(m_poly2.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_poly1.on_mouse_button_up(x, y)) + { + force_redraw(); + } + if(m_poly2.on_mouse_button_up(x, y)) + { + force_redraw(); + } + } + + + virtual void on_key(int x, int y, unsigned key, unsigned flags) + { + } + + + virtual void on_ctrl_change() + { + if(m_animate.status() != m_prev_animate) + { + if(m_animate.status()) + { + on_init(); + int i; + for(i = 0; i < 6; i++) + { + m_dx1[i] = ((rand() % 1000) - 500) * 0.01; + m_dy1[i] = ((rand() % 1000) - 500) * 0.01; + m_dx2[i] = ((rand() % 1000) - 500) * 0.01; + m_dy2[i] = ((rand() % 1000) - 500) * 0.01; + } + wait_mode(false); + } + else + { + wait_mode(true); + } + m_prev_animate = m_animate.status(); + } + } + + + void move_point(double& x, double& y, double& dx, double& dy) + { + if(x < 0.0) { x = 0.0; dx = -dx; } + if(x > width()) { x = width(); dx = -dx; } + if(y < 0.0) { y = 0.0; dy = -dy; } + if(y > height()) { y = height(); dy = -dy; } + x += dx; + y += dy; + } + + + void normalize_point(unsigned i) + { + double d = agg::calc_distance(m_poly1.xn(i), m_poly1.yn(i), + m_poly2.xn(i), m_poly2.yn(i)); + // 28.8 is 20 * sqrt(2) + if(d > 28.28) + { + m_poly2.xn(i) = m_poly1.xn(i) + (m_poly2.xn(i) - m_poly1.xn(i)) * 28.28 / d; + m_poly2.yn(i) = m_poly1.yn(i) + (m_poly2.yn(i) - m_poly1.yn(i)) * 28.28 / d; + } + } + + + + virtual void on_idle() + { + int i; + for(i = 0; i < 6; i++) + { + move_point(m_poly1.xn(i), m_poly1.yn(i), m_dx1[i], m_dy1[i]); + move_point(m_poly2.xn(i), m_poly2.yn(i), m_dx2[i], m_dy2[i]); + normalize_point(i); + } + force_redraw(); + } + +}; + + + + + + +int agg_main(int argc, char* argv[]) +{ + the_application app(pix_format, flip_y); + app.caption("AGG Example. Non-linear \"Along-A-Curve\" Transformer"); + + if(app.init(600, 600, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + + + + + + + + + diff --git a/examples/trans_polar.cpp b/examples/trans_polar.cpp new file mode 100644 index 0000000..4d6253b --- /dev/null +++ b/examples/trans_polar.cpp @@ -0,0 +1,202 @@ +#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_trans_affine.h" +#include "agg_conv_transform.h" +#include "agg_conv_segmentator.h" +#include "platform/agg_platform_support.h" +#include "ctrl/agg_slider_ctrl.h" +#include "ctrl/agg_cbox_ctrl.h" + +#define AGG_BGR24 +//#define AGG_BGR96 +#include "pixel_formats.h" + +enum flip_y_e { flip_y = true }; + + +namespace agg +{ + + + template<class ColorT, class Ctrl, class Pipeline> class transformed_control + { + public: + transformed_control(Ctrl& ctrl, Pipeline& pl) : + m_ctrl(ctrl), + m_pipeline(pl) + {} + + unsigned num_paths() { return m_ctrl.num_paths(); } + void rewind(unsigned path_id) { m_pipeline.rewind(path_id); } + unsigned vertex(double* x, double* y) { return m_pipeline.vertex(x, y); } + const ColorT color(unsigned i) const { return m_ctrl.color(i); } + + private: + Ctrl& m_ctrl; + Pipeline& m_pipeline; + }; + + + + + class trans_polar + { + public: + trans_polar() : + m_base_angle(1.0), + m_base_scale(1.0), + m_base_x(0.0), + m_base_y(0.0), + m_translation_x(0.0), + m_translation_y(0.0), + m_spiral(0.0) + {} + + void base_scale(double v) { m_base_scale = v; } + void full_circle(double v) { m_base_angle = 2.0 * pi / v; } + void base_offset(double dx, double dy) { m_base_x = dx; m_base_y = dy; } + void translation(double dx, double dy) { m_translation_x = dx; m_translation_y = dy;} + void spiral(double v) { m_spiral = v; } + + void transform(double* x, double* y) const + { + double x1 = (*x + m_base_x) * m_base_angle; + double y1 = (*y + m_base_y) * m_base_scale + (*x * m_spiral); + *x = cos(x1) * y1 + m_translation_x; + *y = sin(x1) * y1 + m_translation_y; + } + + private: + double m_base_angle; + double m_base_scale; + double m_base_x; + double m_base_y; + double m_translation_x; + double m_translation_y; + double m_spiral; + }; + + + + + + + + +} + + + + + + + + + + + + + + + +class the_application : public agg::platform_support +{ + agg::slider_ctrl<color_type> m_slider1; + agg::slider_ctrl<color_type> m_slider_spiral; + agg::slider_ctrl<color_type> m_slider_base_y; + +public: + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), + m_slider1 (10, 10, 600-10, 17, !flip_y), + m_slider_spiral(10, 10+20, 600-10, 17+20, !flip_y), + m_slider_base_y(10, 10+40, 600-10, 17+40, !flip_y) + { + add_ctrl(m_slider1); + m_slider1.range(0.0, 100.0); + m_slider1.num_steps(5); + m_slider1.value(32.0); + m_slider1.label("Some Value=%1.0f"); + + add_ctrl(m_slider_spiral); + m_slider_spiral.label("Spiral=%.3f"); + m_slider_spiral.range(-0.1, 0.1); + m_slider_spiral.value(0.0); + + add_ctrl(m_slider_base_y); + m_slider_base_y.label("Base Y=%.3f"); + m_slider_base_y.range(50.0, 200.0); + m_slider_base_y.value(120.0); + } + + + virtual ~the_application() + { + } + + + virtual void on_init() + { + } + + + virtual void on_draw() + { + 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 ren(rb); + agg::scanline_u8 sl; + + rb.clear(agg::rgba(1,1,1)); + + agg::rasterizer_scanline_aa<> ras; + + agg::render_ctrl(ras, sl, rb, m_slider1); + agg::render_ctrl(ras, sl, rb, m_slider_spiral); + agg::render_ctrl(ras, sl, rb, m_slider_base_y); + + + typedef agg::conv_segmentator<agg::slider_ctrl<color_type> > conv_segmentator_type; + typedef agg::conv_transform<conv_segmentator_type, agg::trans_polar> conv_transform_type; + + agg::trans_polar trans; + trans.full_circle(-600); + trans.base_scale(-1.0); + trans.base_offset(0.0, m_slider_base_y.value()); + trans.translation(width() / 2.0, height() / 2.0 + 30.0); + trans.spiral(-m_slider_spiral.value()); + + conv_segmentator_type segm(m_slider1); + conv_transform_type pipeline(segm, trans); + + agg::transformed_control<agg::srgba8, + agg::slider_ctrl<color_type>, + conv_transform_type> ctrl(m_slider1, pipeline); + + + agg::render_ctrl(ras, sl, rb, ctrl); + } + + +}; + + +int agg_main(int argc, char* argv[]) +{ + the_application app(pix_format, flip_y); + app.caption("AGG Example. Polar Transformer"); + + if(app.init(600, 400, agg::window_resize)) + { + return app.run(); + } + return 1; +} + diff --git a/examples/truetype_test.cpp b/examples/truetype_test.cpp new file mode 100644 index 0000000..4b0baab --- /dev/null +++ b/examples/truetype_test.cpp @@ -0,0 +1,450 @@ +#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_win32_tt.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" + + +enum flip_y_e { flip = true }; + +typedef char char_type; + +static char_type text[] = +//"0123456789ABCDEFGHIJKLMNOPRSTUVWXYZabcdefghijklmnoprstuvwxyz " +" 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. "; + + +#define AGG_BGR24 +#include "pixel_formats.h" + +bool text_flip = false; + + +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_win32_tt_int32 font_engine_type; + typedef agg::font_cache_manager<font_engine_type> font_manager_type; + + agg::rbox_ctrl<agg::srgba8> m_ren_type; + agg::slider_ctrl<agg::srgba8> m_height; + agg::slider_ctrl<agg::srgba8> m_width; + agg::slider_ctrl<agg::srgba8> m_weight; + agg::cbox_ctrl<agg::srgba8> m_hinting; + agg::cbox_ctrl<agg::srgba8> m_kerning; + agg::cbox_ctrl<agg::srgba8> 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) + typedef agg::conv_curve<font_manager_type::path_adaptor_type> conv_curve_type; + typedef agg::conv_contour<conv_curve_type> conv_contour_type; + + conv_curve_type m_curves; + conv_contour_type m_contour; + +public: + the_application(HDC dc, agg::pix_format_e format, bool flip) : + agg::platform_support(format, flip), + m_ren_type (5.0, 5.0, 5.0+150.0, 110.0, !flip), + m_height (160, 10.0, 640-5.0, 18.0, !flip), + m_width (160, 30.0, 640-5.0, 38.0, !flip), + m_weight (160, 50.0, 640-5.0, 58.0, !flip), + m_hinting (160, 65.0, "Hinting", !flip), + m_kerning (160, 80.0, "Kerning", !flip), + m_performance (160, 95.0, "Test Performance", !flip), + m_feng(dc), + 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(-2, 2); + m_weight.text_thickness(1.5); + add_ctrl(m_weight); + m_weight.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_method(agg::curve_div); +// m_curves.approximation_scale(0.5); +// m_curves.angle_tolerance(0.3); + 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); + + m_feng.hinting(m_hinting.status()); + m_feng.height(m_height.value()); + + // Font width in Windows is strange. MSDN says, + // "specifies the average width", but there's no clue what + // this "average width" means. It'd be logical to specify + // the width with regard to the font height, like it's done in + // FreeType. That is, width == height should mean the "natural", + // not distorted glyphs. In Windows you have to specify + // the absolute width, which is very stupid and hard to use + // in practice. + //------------------------- + m_feng.width((m_width.value() == m_height.value()) ? 0.0 : m_width.value() / 2.4); + m_feng.italic(true); + m_feng.flip_y(text_flip); + + agg::trans_affine mtx; + //mtx *= agg::trans_affine_skewing(-0.3, 0); + mtx *= agg::trans_affine_rotation(agg::deg2rad(-4.0)); + m_feng.transform(mtx); + + if(m_feng.create_font("Arial", gren)) + { + m_fman.precache(' ', 127); + + double x = 10.0; + double y0 = height() - m_height.value() - 10.0; + double y = y0; + const char_type* 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) + { + 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); + break; + } + + // increment pen position + x += glyph->advance_x; + y += glyph->advance_y; + ++num_glyphs; + } + ++p; + } + } + 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(0.5)); + } + else + { + m_feng.gamma(agg::gamma_none()); + } + + draw_text(ras, sl, ren_solid, ren_bin); + + 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_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) + { + text_flip = !text_flip; + force_redraw(); + } + + +}; + + + +int agg_main(int argc, char* argv[]) +{ + HDC dc = ::GetDC(0); + the_application app(dc, agg::pix_format_bgr24, flip); + app.caption("AGG Example. Rendering TrueType Fonts with WinAPI"); + + if(app.init(640, 520, agg::window_resize)) + { + return app.run(); + } + ::ReleaseDC(0, dc); + return 1; +} + + diff --git a/examples/win32_api/Makefile b/examples/win32_api/Makefile new file mode 100644 index 0000000..a314b9e --- /dev/null +++ b/examples/win32_api/Makefile @@ -0,0 +1,107 @@ +# +# This makefile can be used to build Win32 application under Cygwin +# + +all: + cd aa_demo; make + cd aa_test; make + cd agg2d_demo; make + cd alpha_gradient; make + cd alpha_mask; make + cd alpha_mask2; make + cd alpha_mask3; make + cd bezier_div; make + cd bspline; make + cd circles; make + cd compositing; make + cd component_rendering; make + cd conv_contour; make + cd conv_dash_marker; make + cd conv_stroke; make + cd distortions; make + cd gamma_correction; make + cd gamma_ctrl; make + cd gouraud; make + cd gpc_test; make + cd gradients; make + cd graph_test; make + cd idea; make + cd image_alpha; make + cd image_filters; make + cd image_filters2; make + cd image_fltr_graph; make + cd image_transforms; make + cd image_perspective; make + cd image_resample; make + cd image1; make + cd line_patterns; make + cd lion; make + cd lion_lens; make + cd lion_outline; make + cd mol_view; make + cd multi_clip; make + cd pattern_fill; make + cd perspective; make + cd polymorphic_renderer; make + cd raster_text; make + cd rasterizers; make + cd rasterizers2; make + cd rounded_rect; make + cd scanline_boolean; make + cd scanline_boolean2; make + cd simple_blur; make + cd trans_polar; make + cd trans_curve1; make + cd trans_curve2; make + cd truetype_test; make +clean: + cd aa_demo; make clean + cd aa_test; make clean + cd alpha_gradient; make clean + cd alpha_mask; make clean + cd alpha_mask2; make clean + cd alpha_mask3; make clean + cd bezier_div; make clean + cd bspline; make clean + cd circles; make clean + cd compositing; make clean + cd component_rendering; make clean + cd conv_contour; make clean + cd conv_dash_marker; make clean + cd conv_stroke; make clean + cd distortions; make clean + cd gamma_correction; make clean + cd gamma_ctrl; make clean + cd gouraud; make clean + cd gpc_test; make clean + cd gradients; make clean + cd graph_test; make clean + cd idea; make clean + cd image_alpha; make clean + cd image_filters; make clean + cd image_filters2; make clean + cd image_fltr_graph; make clean + cd image_perspective; make clean + cd image_resample; make clean + cd image_transforms; make clean + cd images1; make clean + cd line_patterns; make clean + cd lion; make clean + cd lion_lens; make clean + cd lion_outline; make clean + cd mol_view; make clean + cd multi_clip; make clean + cd pattern_fill; make clean + cd perspective; make clean + cd polymorphic_renderer; make clean + cd raster_text; make clean + cd rasterizers; make clean + cd rasterizers2; make clean + cd rounded_rect; make clean + cd scanline_boolean; make clean + cd scanline_boolean2; make clean + cd simple_blur; make clean + cd trans_polar; make clean + cd trans_curve1; make clean + cd trans_curve2; make clean + cd truetype_test; make clean diff --git a/examples/win32_api/aa_demo/Makefile b/examples/win32_api/aa_demo/Makefile new file mode 100644 index 0000000..61aac07 --- /dev/null +++ b/examples/win32_api/aa_demo/Makefile @@ -0,0 +1,39 @@ +# +# This makefile can be used to build a Win32 application under Cygwin or MinGW +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=aa_demo +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/aa_demo/aa_demo.dsp b/examples/win32_api/aa_demo/aa_demo.dsp new file mode 100644 index 0000000..cb6683c --- /dev/null +++ b/examples/win32_api/aa_demo/aa_demo.dsp @@ -0,0 +1,139 @@ +# Microsoft Developer Studio Project File - Name="aa_demo" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=aa_demo - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "aa_demo.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "aa_demo.mak" CFG="aa_demo - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "aa_demo - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "aa_demo - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "aa_demo - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./aa_demo.exe" + +!ELSEIF "$(CFG)" == "aa_demo - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "aa_demo - Win32 Release" +# Name "aa_demo - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\aa_demo.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/aa_demo/aa_demo.dsw b/examples/win32_api/aa_demo/aa_demo.dsw new file mode 100644 index 0000000..99fc2ad --- /dev/null +++ b/examples/win32_api/aa_demo/aa_demo.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "aa_demo"=.\aa_demo.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/aa_demo/aa_demo.vcxproj b/examples/win32_api/aa_demo/aa_demo.vcxproj new file mode 100644 index 0000000..0cc0d5b --- /dev/null +++ b/examples/win32_api/aa_demo/aa_demo.vcxproj @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B0426FB2-76DF-32F0-0774-4A6998FC1E54}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\aa_demo.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\aa_demo.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\aa_demo.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\aa_demo.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\aa_demo.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\aa_demo.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\aa_demo.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\aa_demo.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\aa_demo.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/aa_test/Makefile b/examples/win32_api/aa_test/Makefile new file mode 100644 index 0000000..37f718a --- /dev/null +++ b/examples/win32_api/aa_test/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=aa_test +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/aa_test/aa_test.dsp b/examples/win32_api/aa_test/aa_test.dsp new file mode 100644 index 0000000..72fd8c9 --- /dev/null +++ b/examples/win32_api/aa_test/aa_test.dsp @@ -0,0 +1,143 @@ +# Microsoft Developer Studio Project File - Name="aa_test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=aa_test - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "aa_test.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "aa_test.mak" CFG="aa_test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "aa_test - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "aa_test - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "aa_test - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./aa_test.exe" + +!ELSEIF "$(CFG)" == "aa_test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "aa_test - Win32 Release" +# Name "aa_test - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\aa_test.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_dash.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/aa_test/aa_test.dsw b/examples/win32_api/aa_test/aa_test.dsw new file mode 100644 index 0000000..b457d8c --- /dev/null +++ b/examples/win32_api/aa_test/aa_test.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "aa_test"=.\aa_test.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/aa_test/aa_test.vcxproj b/examples/win32_api/aa_test/aa_test.vcxproj new file mode 100644 index 0000000..7773049 --- /dev/null +++ b/examples/win32_api/aa_test/aa_test.vcxproj @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\aa_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\aa_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\aa_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\aa_test.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\aa_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\aa_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\aa_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\aa_test.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\aa_test.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_dash.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/agg.props b/examples/win32_api/agg.props new file mode 100644 index 0000000..410d8e2 --- /dev/null +++ b/examples/win32_api/agg.props @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ImportGroup Label="PropertySheets" /> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup /> +</Project> \ No newline at end of file diff --git a/examples/win32_api/agg2d_demo/Makefile b/examples/win32_api/agg2d_demo/Makefile new file mode 100644 index 0000000..98aac0c --- /dev/null +++ b/examples/win32_api/agg2d_demo/Makefile @@ -0,0 +1,46 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=agg2d_demo +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I../../../agg2d \ +-I../../../font_win32_tt \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../agg2d/agg2d.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp \ +../../../font_win32_tt/agg_font_win32_tt.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../agg2d/agg2d.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f ../../../src/platform/$(PLATFORM)/agg_win32_bmp.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/agg2d_demo/agg2d_demo.vcxproj b/examples/win32_api/agg2d_demo/agg2d_demo.vcxproj new file mode 100644 index 0000000..b263bcd --- /dev/null +++ b/examples/win32_api/agg2d_demo/agg2d_demo.vcxproj @@ -0,0 +1,86 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6015656F-2EE0-42FD-9EE3-DE54A429EE00}</ProjectGuid> + <RootNamespace>agg2d_demo</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup /> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../../../include;../../../agg2d;../../../font_win32_tt</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <AdditionalIncludeDirectories>../../../include;../../../agg2d;../../../font_win32_tt</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\font_win32_tt\agg_font_win32_tt.cpp" /> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\agg_rounded_rect.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\..\agg2d\agg2d.cpp" /> + <ClCompile Include="..\..\agg2d_demo.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/alpha_gradient/Makefile b/examples/win32_api/alpha_gradient/Makefile new file mode 100644 index 0000000..281bf8b --- /dev/null +++ b/examples/win32_api/alpha_gradient/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=alpha_gradient +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/alpha_gradient/alpha_gradient.dsp b/examples/win32_api/alpha_gradient/alpha_gradient.dsp new file mode 100644 index 0000000..7b47ec1 --- /dev/null +++ b/examples/win32_api/alpha_gradient/alpha_gradient.dsp @@ -0,0 +1,151 @@ +# Microsoft Developer Studio Project File - Name="alpha_gradient" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=alpha_gradient - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "alpha_gradient.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "alpha_gradient.mak" CFG="alpha_gradient - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "alpha_gradient - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "alpha_gradient - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "alpha_gradient - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./alpha_gradient.exe" + +!ELSEIF "$(CFG)" == "alpha_gradient - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "alpha_gradient - Win32 Release" +# Name "alpha_gradient - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_spline_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\alpha_gradient.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_span_gradient.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_gradient_alpha.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/alpha_gradient/alpha_gradient.dsw b/examples/win32_api/alpha_gradient/alpha_gradient.dsw new file mode 100644 index 0000000..162b841 --- /dev/null +++ b/examples/win32_api/alpha_gradient/alpha_gradient.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "alpha_gradient"=.\alpha_gradient.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/alpha_gradient/alpha_gradient.vcxproj b/examples/win32_api/alpha_gradient/alpha_gradient.vcxproj new file mode 100644 index 0000000..c325445 --- /dev/null +++ b/examples/win32_api/alpha_gradient/alpha_gradient.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{73275357-2B4C-6183-1E18-C8C41B62F6DF}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\alpha_gradient.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\alpha_gradient.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\alpha_gradient.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\alpha_gradient.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\alpha_gradient.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\alpha_gradient.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\alpha_gradient.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\alpha_gradient.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_spline_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\alpha_gradient.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_span_gradient.h" /> + <ClInclude Include="..\..\..\include\agg_span_gradient_alpha.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/alpha_mask/Makefile b/examples/win32_api/alpha_mask/Makefile new file mode 100644 index 0000000..a74936f --- /dev/null +++ b/examples/win32_api/alpha_mask/Makefile @@ -0,0 +1,41 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=alpha_mask +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../parse_lion.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/alpha_mask/alpha_mask.dsp b/examples/win32_api/alpha_mask/alpha_mask.dsp new file mode 100644 index 0000000..429da95 --- /dev/null +++ b/examples/win32_api/alpha_mask/alpha_mask.dsp @@ -0,0 +1,139 @@ +# Microsoft Developer Studio Project File - Name="alpha_mask" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=alpha_mask - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "alpha_mask.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "alpha_mask.mak" CFG="alpha_mask - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "alpha_mask - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "alpha_mask - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "alpha_mask - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./alpha_mask.exe" + +!ELSEIF "$(CFG)" == "alpha_mask - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "alpha_mask - Win32 Release" +# Name "alpha_mask - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\alpha_mask.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\parse_lion.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/alpha_mask/alpha_mask.dsw b/examples/win32_api/alpha_mask/alpha_mask.dsw new file mode 100644 index 0000000..9a2381c --- /dev/null +++ b/examples/win32_api/alpha_mask/alpha_mask.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "alpha_mask"=.\alpha_mask.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/alpha_mask/alpha_mask.vcxproj b/examples/win32_api/alpha_mask/alpha_mask.vcxproj new file mode 100644 index 0000000..5dc7594 --- /dev/null +++ b/examples/win32_api/alpha_mask/alpha_mask.vcxproj @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{37C8795F-976D-BCF8-639C-FF2DC2AC17CE}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\alpha_mask.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\alpha_mask.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\alpha_mask.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\alpha_mask.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\alpha_mask.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\alpha_mask.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\alpha_mask.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\alpha_mask.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\alpha_mask.cpp" /> + <ClCompile Include="..\..\parse_lion.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/alpha_mask2/Makefile b/examples/win32_api/alpha_mask2/Makefile new file mode 100644 index 0000000..c272264 --- /dev/null +++ b/examples/win32_api/alpha_mask2/Makefile @@ -0,0 +1,41 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=alpha_mask2 +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../parse_lion.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/alpha_mask2/alpha_mask2.dsp b/examples/win32_api/alpha_mask2/alpha_mask2.dsp new file mode 100644 index 0000000..3249310 --- /dev/null +++ b/examples/win32_api/alpha_mask2/alpha_mask2.dsp @@ -0,0 +1,155 @@ +# Microsoft Developer Studio Project File - Name="alpha_mask2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=alpha_mask2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "alpha_mask2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "alpha_mask2.mak" CFG="alpha_mask2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "alpha_mask2 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "alpha_mask2 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "alpha_mask2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./alpha_mask2.exe" + +!ELSEIF "$(CFG)" == "alpha_mask2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "alpha_mask2 - Win32 Release" +# Name "alpha_mask2 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_aa_basics.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_profile_aa.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\alpha_mask2.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\parse_lion.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_pixfmt_amask_adaptor.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/alpha_mask2/alpha_mask2.dsw b/examples/win32_api/alpha_mask2/alpha_mask2.dsw new file mode 100644 index 0000000..d952cde --- /dev/null +++ b/examples/win32_api/alpha_mask2/alpha_mask2.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "alpha_mask2"=.\alpha_mask2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/alpha_mask2/alpha_mask2.vcxproj b/examples/win32_api/alpha_mask2/alpha_mask2.vcxproj new file mode 100644 index 0000000..9250fb7 --- /dev/null +++ b/examples/win32_api/alpha_mask2/alpha_mask2.vcxproj @@ -0,0 +1,163 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{32435053-471C-9795-E555-A6BD34E3B70A}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\alpha_mask2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\alpha_mask2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\alpha_mask2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\alpha_mask2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\alpha_mask2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\alpha_mask2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\alpha_mask2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\alpha_mask2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_aa_basics.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_profile_aa.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\alpha_mask2.cpp" /> + <ClCompile Include="..\..\parse_lion.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_pixfmt_amask_adaptor.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/alpha_mask3/Makefile b/examples/win32_api/alpha_mask3/Makefile new file mode 100644 index 0000000..5693472 --- /dev/null +++ b/examples/win32_api/alpha_mask3/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=alpha_mask3 +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../make_arrows.cpp \ +../../make_gb_poly.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../*.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/alpha_mask3/alpha_mask3.dsp b/examples/win32_api/alpha_mask3/alpha_mask3.dsp new file mode 100644 index 0000000..5768b56 --- /dev/null +++ b/examples/win32_api/alpha_mask3/alpha_mask3.dsp @@ -0,0 +1,155 @@ +# Microsoft Developer Studio Project File - Name="alpha_mask3" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=alpha_mask3 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "alpha_mask3.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "alpha_mask3.mak" CFG="alpha_mask3 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "alpha_mask3 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "alpha_mask3 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "alpha_mask3 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /I "../../../gpc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./alpha_mask3.exe" + +!ELSEIF "$(CFG)" == "alpha_mask3 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../gpc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "alpha_mask3 - Win32 Release" +# Name "alpha_mask3 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\alpha_mask3.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\make_arrows.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\make_gb_poly.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/alpha_mask3/alpha_mask3.dsw b/examples/win32_api/alpha_mask3/alpha_mask3.dsw new file mode 100644 index 0000000..5ff535e --- /dev/null +++ b/examples/win32_api/alpha_mask3/alpha_mask3.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "alpha_mask3"=.\alpha_mask3.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/alpha_mask3/alpha_mask3.vcxproj b/examples/win32_api/alpha_mask3/alpha_mask3.vcxproj new file mode 100644 index 0000000..3dd74a3 --- /dev/null +++ b/examples/win32_api/alpha_mask3/alpha_mask3.vcxproj @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;../../../gpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\alpha_mask3.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\alpha_mask3.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\alpha_mask3.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\alpha_mask3.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;../../../gpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\alpha_mask3.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\alpha_mask3.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\alpha_mask3.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\alpha_mask3.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\alpha_mask3.cpp" /> + <ClCompile Include="..\..\make_arrows.cpp" /> + <ClCompile Include="..\..\make_gb_poly.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/bezier_div/Makefile b/examples/win32_api/bezier_div/Makefile new file mode 100644 index 0000000..563fb2c --- /dev/null +++ b/examples/win32_api/bezier_div/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=bezier_div +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../interactive_polygon.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../interactive_polygon.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/bezier_div/bezier_div.dsp b/examples/win32_api/bezier_div/bezier_div.dsp new file mode 100644 index 0000000..b05562d --- /dev/null +++ b/examples/win32_api/bezier_div/bezier_div.dsp @@ -0,0 +1,175 @@ +# Microsoft Developer Studio Project File - Name="bezier_div" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=bezier_div - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "bezier_div.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "bezier_div.mak" CFG="bezier_div - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "bezier_div - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "bezier_div - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "bezier_div - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./bezier_div.exe" + +!ELSEIF "$(CFG)" == "bezier_div - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "bezier_div - Win32 Release" +# Name "bezier_div - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_bezier_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_aa_basics.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_profile_aa.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_polygon_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_dash.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\bezier_div.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/bezier_div/bezier_div.dsw b/examples/win32_api/bezier_div/bezier_div.dsw new file mode 100644 index 0000000..90da71e --- /dev/null +++ b/examples/win32_api/bezier_div/bezier_div.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "bezier_div"=.\bezier_div.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/bezier_div/bezier_div.vcxproj b/examples/win32_api/bezier_div/bezier_div.vcxproj new file mode 100644 index 0000000..d999de9 --- /dev/null +++ b/examples/win32_api/bezier_div/bezier_div.vcxproj @@ -0,0 +1,164 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{1C36D677-7993-4E51-2773-B4094FB8EE2A}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\bezier_div.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\bezier_div.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\bezier_div.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\bezier_div.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\bezier_div.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\bezier_div.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\bezier_div.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\bezier_div.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_bezier_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_aa_basics.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_profile_aa.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_polygon_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_dash.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\bezier_div.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/blend_color/Makefile b/examples/win32_api/blend_color/Makefile new file mode 100644 index 0000000..8f7cb14 --- /dev/null +++ b/examples/win32_api/blend_color/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=blend_color +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/blend_color/blend_color.dsp b/examples/win32_api/blend_color/blend_color.dsp new file mode 100644 index 0000000..de2141f --- /dev/null +++ b/examples/win32_api/blend_color/blend_color.dsp @@ -0,0 +1,163 @@ +# Microsoft Developer Studio Project File - Name="blend_color" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=blend_color - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "blend_color.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "blend_color.mak" CFG="blend_color - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "blend_color - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "blend_color - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "blend_color - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./blend_color.exe" + +!ELSEIF "$(CFG)" == "blend_color - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "blend_color - Win32 Release" +# Name "blend_color - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_arrowhead.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_polygon_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\blend_color.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/blend_color/blend_color.dsw b/examples/win32_api/blend_color/blend_color.dsw new file mode 100644 index 0000000..91ba1b7 --- /dev/null +++ b/examples/win32_api/blend_color/blend_color.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "blend_color"=.\blend_color.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/blend_color/blend_color.vcxproj b/examples/win32_api/blend_color/blend_color.vcxproj new file mode 100644 index 0000000..870b890 --- /dev/null +++ b/examples/win32_api/blend_color/blend_color.vcxproj @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A9DD4081-1935-AF41-62EF-B23E97832EC7}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\blend_color.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\blend_color.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\blend_color.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\blend_color.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\blend_color.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\blend_color.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\blend_color.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\blend_color.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_arrowhead.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_polygon_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\blend_color.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/blur/Makefile b/examples/win32_api/blur/Makefile new file mode 100644 index 0000000..b00ffa5 --- /dev/null +++ b/examples/win32_api/blur/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=blur +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/blur/blur.dsp b/examples/win32_api/blur/blur.dsp new file mode 100644 index 0000000..95949c4 --- /dev/null +++ b/examples/win32_api/blur/blur.dsp @@ -0,0 +1,163 @@ +# Microsoft Developer Studio Project File - Name="blur" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=blur - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "blur.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "blur.mak" CFG="blur - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "blur - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "blur - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "blur - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./blur.exe" + +!ELSEIF "$(CFG)" == "blur - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "blur - Win32 Release" +# Name "blur - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_arrowhead.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_polygon_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\blur.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/blur/blur.dsw b/examples/win32_api/blur/blur.dsw new file mode 100644 index 0000000..9e2bf4e --- /dev/null +++ b/examples/win32_api/blur/blur.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "blur"=.\blur.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/blur/blur.vcxproj b/examples/win32_api/blur/blur.vcxproj new file mode 100644 index 0000000..82cebc3 --- /dev/null +++ b/examples/win32_api/blur/blur.vcxproj @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C9681374-4905-6476-F859-F756197FCB9F}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\blur.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\blur.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\blur.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\blur.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\blur.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\blur.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\blur.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\blur.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_arrowhead.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_polygon_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\blur.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/bspline/Makefile b/examples/win32_api/bspline/Makefile new file mode 100644 index 0000000..cf885d8 --- /dev/null +++ b/examples/win32_api/bspline/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=bspline +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../interactive_polygon.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../interactive_polygon.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/bspline/bspline.dsp b/examples/win32_api/bspline/bspline.dsp new file mode 100644 index 0000000..7570354 --- /dev/null +++ b/examples/win32_api/bspline/bspline.dsp @@ -0,0 +1,151 @@ +# Microsoft Developer Studio Project File - Name="bspline" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=bspline - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "bspline.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "bspline.mak" CFG="bspline - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "bspline - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "bspline - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "bspline - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./bspline.exe" + +!ELSEIF "$(CFG)" == "bspline - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "bspline - Win32 Release" +# Name "bspline - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\interactive_polygon.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/bspline/bspline.dsw b/examples/win32_api/bspline/bspline.dsw new file mode 100644 index 0000000..ca344ed --- /dev/null +++ b/examples/win32_api/bspline/bspline.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "bspline"=.\bspline.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/bspline/bspline.vcxproj b/examples/win32_api/bspline/bspline.vcxproj new file mode 100644 index 0000000..4e624ea --- /dev/null +++ b/examples/win32_api/bspline/bspline.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{369F608F-B992-7E21-FF16-CAC95B52382F}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\bspline.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\bspline.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\bspline.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\bspline.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\bspline.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\bspline.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\bspline.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\bspline.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_bspline.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\bspline.cpp" /> + <ClCompile Include="..\..\interactive_polygon.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/circles/Makefile b/examples/win32_api/circles/Makefile new file mode 100644 index 0000000..17a10fc --- /dev/null +++ b/examples/win32_api/circles/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=circles +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/circles/circles.dsp b/examples/win32_api/circles/circles.dsp new file mode 100644 index 0000000..880b6f6 --- /dev/null +++ b/examples/win32_api/circles/circles.dsp @@ -0,0 +1,157 @@ +# Microsoft Developer Studio Project File - Name="circles" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=circles - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "circles.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "circles.mak" CFG="circles - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "circles - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "circles - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "circles - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./circles.exe" + +!ELSEIF "$(CFG)" == "circles - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "circles - Win32 Release" +# Name "circles - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_scale_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\circles.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_gsv_text.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\platform\agg_platform_support.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\ctrl\agg_scale_ctrl.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/circles/circles.dsw b/examples/win32_api/circles/circles.dsw new file mode 100644 index 0000000..fde69cb --- /dev/null +++ b/examples/win32_api/circles/circles.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "circles"=.\circles.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/circles/circles.vcxproj b/examples/win32_api/circles/circles.vcxproj new file mode 100644 index 0000000..912b574 --- /dev/null +++ b/examples/win32_api/circles/circles.vcxproj @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\circles.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\circles.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\circles.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\circles.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\circles.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\circles.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\circles.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\circles.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_scale_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\circles.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_gsv_text.h" /> + <ClInclude Include="..\..\..\include\platform\agg_platform_support.h" /> + <ClInclude Include="..\..\..\include\ctrl\agg_scale_ctrl.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/component_rendering/Makefile b/examples/win32_api/component_rendering/Makefile new file mode 100644 index 0000000..b85e551 --- /dev/null +++ b/examples/win32_api/component_rendering/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=component_rendering +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/component_rendering/component_rendering.dsp b/examples/win32_api/component_rendering/component_rendering.dsp new file mode 100644 index 0000000..81aaf03 --- /dev/null +++ b/examples/win32_api/component_rendering/component_rendering.dsp @@ -0,0 +1,137 @@ +# Microsoft Developer Studio Project File - Name="component_rendering" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=component_rendering - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "component_rendering.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "component_rendering.mak" CFG="component_rendering - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "component_rendering - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "component_rendering - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "component_rendering - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./component_rendering.exe" + +!ELSEIF "$(CFG)" == "component_rendering - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "component_rendering - Win32 Release" +# Name "component_rendering - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\component_rendering.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/component_rendering/component_rendering.dsw b/examples/win32_api/component_rendering/component_rendering.dsw new file mode 100644 index 0000000..eae0d30 --- /dev/null +++ b/examples/win32_api/component_rendering/component_rendering.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "component_rendering"=.\component_rendering.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/component_rendering/component_rendering.vcxproj b/examples/win32_api/component_rendering/component_rendering.vcxproj new file mode 100644 index 0000000..b08a637 --- /dev/null +++ b/examples/win32_api/component_rendering/component_rendering.vcxproj @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{E67DB44E-2CE0-5DC6-66A0-66146D7176DE}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\component_rendering.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\component_rendering.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\component_rendering.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\component_rendering.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\component_rendering.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\component_rendering.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\component_rendering.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\component_rendering.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\component_rendering.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/compositing/Makefile b/examples/win32_api/compositing/Makefile new file mode 100644 index 0000000..7ef50d2 --- /dev/null +++ b/examples/win32_api/compositing/Makefile @@ -0,0 +1,39 @@ +# +# This makefile can be used to build a Win32 application under Cygwin or MinGW +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=compositing +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/compositing/compositing.dsp b/examples/win32_api/compositing/compositing.dsp new file mode 100644 index 0000000..f41f6e2 --- /dev/null +++ b/examples/win32_api/compositing/compositing.dsp @@ -0,0 +1,159 @@ +# Microsoft Developer Studio Project File - Name="compositing" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=compositing - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "compositing.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "compositing.mak" CFG="compositing - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "compositing - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "compositing - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "compositing - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./compositing.exe" + +!ELSEIF "$(CFG)" == "compositing - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "compositing - Win32 Release" +# Name "compositing - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_rounded_rect.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\compositing.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_pixfmt_rgba.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_rendering_buffer_dynarow.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/compositing/compositing.dsw b/examples/win32_api/compositing/compositing.dsw new file mode 100644 index 0000000..f26e02d --- /dev/null +++ b/examples/win32_api/compositing/compositing.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "compositing"=.\compositing.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/compositing/compositing.vcxproj b/examples/win32_api/compositing/compositing.vcxproj new file mode 100644 index 0000000..98a84ff --- /dev/null +++ b/examples/win32_api/compositing/compositing.vcxproj @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\compositing.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\compositing.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\compositing.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\compositing.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\compositing.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\compositing.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\compositing.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\compositing.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_rounded_rect.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\compositing.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_pixfmt_rgba.h" /> + <ClInclude Include="..\..\..\include\agg_rendering_buffer_dynarow.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/compositing/readme b/examples/win32_api/compositing/readme new file mode 100644 index 0000000..226ae60 --- /dev/null +++ b/examples/win32_api/compositing/readme @@ -0,0 +1 @@ +Copy compositing.bmp from ..\..\art before running this example. diff --git a/examples/win32_api/compositing2/Makefile b/examples/win32_api/compositing2/Makefile new file mode 100644 index 0000000..7ef50d2 --- /dev/null +++ b/examples/win32_api/compositing2/Makefile @@ -0,0 +1,39 @@ +# +# This makefile can be used to build a Win32 application under Cygwin or MinGW +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=compositing +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/compositing2/compositing2.dsp b/examples/win32_api/compositing2/compositing2.dsp new file mode 100644 index 0000000..d1d15fa --- /dev/null +++ b/examples/win32_api/compositing2/compositing2.dsp @@ -0,0 +1,163 @@ +# Microsoft Developer Studio Project File - Name="compositing2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=compositing2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "compositing2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "compositing2.mak" CFG="compositing2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "compositing2 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "compositing2 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "compositing2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./compositing2.exe" + +!ELSEIF "$(CFG)" == "compositing2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "compositing2 - Win32 Release" +# Name "compositing2 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_rounded_rect.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\compositing2.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_pixfmt_rgba.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_rendering_buffer_dynarow.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/compositing2/compositing2.dsw b/examples/win32_api/compositing2/compositing2.dsw new file mode 100644 index 0000000..8155708 --- /dev/null +++ b/examples/win32_api/compositing2/compositing2.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "compositing2"=.\compositing2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/compositing2/compositing2.vcxproj b/examples/win32_api/compositing2/compositing2.vcxproj new file mode 100644 index 0000000..89437b7 --- /dev/null +++ b/examples/win32_api/compositing2/compositing2.vcxproj @@ -0,0 +1,163 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{9D610545-E382-D6FB-7D74-8DD26086BF0E}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\compositing2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\compositing2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\compositing2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\compositing2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\compositing2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\compositing2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\compositing2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\compositing2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_rounded_rect.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\compositing2.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_pixfmt_rgba.h" /> + <ClInclude Include="..\..\..\include\agg_rendering_buffer_dynarow.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/conv_contour/Makefile b/examples/win32_api/conv_contour/Makefile new file mode 100644 index 0000000..353a2ca --- /dev/null +++ b/examples/win32_api/conv_contour/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=conv_contour +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/conv_contour/conv_contour.dsp b/examples/win32_api/conv_contour/conv_contour.dsp new file mode 100644 index 0000000..a228ef6 --- /dev/null +++ b/examples/win32_api/conv_contour/conv_contour.dsp @@ -0,0 +1,159 @@ +# Microsoft Developer Studio Project File - Name="conv_contour" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=conv_contour - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "conv_contour.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "conv_contour.mak" CFG="conv_contour - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "conv_contour - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "conv_contour - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "conv_contour - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./conv_contour.exe" + +!ELSEIF "$(CFG)" == "conv_contour - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "conv_contour - Win32 Release" +# Name "conv_contour - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_arrowhead.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\conv_contour.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/conv_contour/conv_contour.dsw b/examples/win32_api/conv_contour/conv_contour.dsw new file mode 100644 index 0000000..fcde274 --- /dev/null +++ b/examples/win32_api/conv_contour/conv_contour.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "conv_contour"=.\conv_contour.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/conv_contour/conv_contour.vcxproj b/examples/win32_api/conv_contour/conv_contour.vcxproj new file mode 100644 index 0000000..ab24adf --- /dev/null +++ b/examples/win32_api/conv_contour/conv_contour.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{762ECE3C-F322-02D1-512A-C903F140FD90}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\conv_contour.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\conv_contour.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\conv_contour.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\conv_contour.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\conv_contour.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\conv_contour.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\conv_contour.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\conv_contour.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_arrowhead.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\conv_contour.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/conv_dash_marker/Makefile b/examples/win32_api/conv_dash_marker/Makefile new file mode 100644 index 0000000..1c171c0 --- /dev/null +++ b/examples/win32_api/conv_dash_marker/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=conv_dash_marker +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/conv_dash_marker/conv_dash_marker.dsp b/examples/win32_api/conv_dash_marker/conv_dash_marker.dsp new file mode 100644 index 0000000..4d8c744 --- /dev/null +++ b/examples/win32_api/conv_dash_marker/conv_dash_marker.dsp @@ -0,0 +1,175 @@ +# Microsoft Developer Studio Project File - Name="conv_dash_marker" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=conv_dash_marker - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "conv_dash_marker.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "conv_dash_marker.mak" CFG="conv_dash_marker - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "conv_dash_marker - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "conv_dash_marker - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "conv_dash_marker - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./conv_dash_marker.exe" + +!ELSEIF "$(CFG)" == "conv_dash_marker - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "conv_dash_marker - Win32 Release" +# Name "conv_dash_marker - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_arrowhead.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_rounded_rect.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_dash.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_markers_term.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_smooth_poly1.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\conv_dash_marker.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/conv_dash_marker/conv_dash_marker.dsw b/examples/win32_api/conv_dash_marker/conv_dash_marker.dsw new file mode 100644 index 0000000..43a9333 --- /dev/null +++ b/examples/win32_api/conv_dash_marker/conv_dash_marker.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "conv_dash_marker"=.\conv_dash_marker.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/conv_dash_marker/conv_dash_marker.vcxproj b/examples/win32_api/conv_dash_marker/conv_dash_marker.vcxproj new file mode 100644 index 0000000..84a5c00 --- /dev/null +++ b/examples/win32_api/conv_dash_marker/conv_dash_marker.vcxproj @@ -0,0 +1,164 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A65DC652-88CF-A922-1AB4-DE39386D66B2}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\conv_dash_marker.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\conv_dash_marker.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\conv_dash_marker.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\conv_dash_marker.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\conv_dash_marker.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\conv_dash_marker.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\conv_dash_marker.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\conv_dash_marker.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_arrowhead.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_rounded_rect.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_dash.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_markers_term.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_smooth_poly1.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\conv_dash_marker.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/conv_stroke/Makefile b/examples/win32_api/conv_stroke/Makefile new file mode 100644 index 0000000..292ba01 --- /dev/null +++ b/examples/win32_api/conv_stroke/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=conv_stroke +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/conv_stroke/conv_stroke.dsp b/examples/win32_api/conv_stroke/conv_stroke.dsp new file mode 100644 index 0000000..95269ca --- /dev/null +++ b/examples/win32_api/conv_stroke/conv_stroke.dsp @@ -0,0 +1,171 @@ +# Microsoft Developer Studio Project File - Name="conv_stroke" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=conv_stroke - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "conv_stroke.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "conv_stroke.mak" CFG="conv_stroke - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "conv_stroke - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "conv_stroke - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "conv_stroke - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./conv_stroke.exe" + +!ELSEIF "$(CFG)" == "conv_stroke - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "conv_stroke - Win32 Release" +# Name "conv_stroke - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_arrowhead.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_rounded_rect.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_dash.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_markers_term.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_smooth_poly1.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\conv_stroke.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/conv_stroke/conv_stroke.dsw b/examples/win32_api/conv_stroke/conv_stroke.dsw new file mode 100644 index 0000000..5e5ec7d --- /dev/null +++ b/examples/win32_api/conv_stroke/conv_stroke.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "conv_stroke"=.\conv_stroke.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/conv_stroke/conv_stroke.vcxproj b/examples/win32_api/conv_stroke/conv_stroke.vcxproj new file mode 100644 index 0000000..3a283a6 --- /dev/null +++ b/examples/win32_api/conv_stroke/conv_stroke.vcxproj @@ -0,0 +1,163 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A6669230-ECD1-D652-159F-08DCE667B630}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\conv_stroke.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\conv_stroke.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\conv_stroke.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\conv_stroke.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\conv_stroke.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\conv_stroke.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\conv_stroke.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\conv_stroke.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_arrowhead.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_rounded_rect.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_dash.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_markers_term.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_smooth_poly1.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\conv_stroke.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/distortions/Makefile b/examples/win32_api/distortions/Makefile new file mode 100644 index 0000000..c99b799 --- /dev/null +++ b/examples/win32_api/distortions/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=distortions +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/distortions/distortions.dsp b/examples/win32_api/distortions/distortions.dsp new file mode 100644 index 0000000..5c6ccdb --- /dev/null +++ b/examples/win32_api/distortions/distortions.dsp @@ -0,0 +1,161 @@ +# Microsoft Developer Studio Project File - Name="distortions" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=distortions - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "distortions.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "distortions.mak" CFG="distortions - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "distortions - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "distortions - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "distortions - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./distortions.exe" +# SUBTRACT LINK32 /profile + +!ELSEIF "$(CFG)" == "distortions - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "distortions - Win32 Release" +# Name "distortions - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\distortions.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_span_interpolator_adaptor.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\..\include\agg_gouraud_attr.h +# End Source File +# End Target +# End Project diff --git a/examples/win32_api/distortions/distortions.dsw b/examples/win32_api/distortions/distortions.dsw new file mode 100644 index 0000000..3ef4757 --- /dev/null +++ b/examples/win32_api/distortions/distortions.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "distortions"=.\distortions.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/distortions/distortions.vcxproj b/examples/win32_api/distortions/distortions.vcxproj new file mode 100644 index 0000000..b0c9757 --- /dev/null +++ b/examples/win32_api/distortions/distortions.vcxproj @@ -0,0 +1,164 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{080665EE-6049-7077-64BA-191B30EA7756}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\distortions.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\distortions.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\distortions.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\distortions.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\distortions.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\distortions.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\distortions.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\distortions.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\distortions.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_span_interpolator_adaptor.h" /> + <ClInclude Include="..\..\..\include\agg_gouraud_attr.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/distortions/readme b/examples/win32_api/distortions/readme new file mode 100644 index 0000000..07d1c1c --- /dev/null +++ b/examples/win32_api/distortions/readme @@ -0,0 +1,5 @@ +Copy spheres.bmp from ..\..\art before running this example +Use the sliders and the radio-buttons to change the parameters of +the distortions. Drag the center of the distortions. +Don't try to understand the shamanic manipulations with affine matrices +because I composed it using the "hit-and-miss" method :-) diff --git a/examples/win32_api/examples.dsw b/examples/win32_api/examples.dsw new file mode 100644 index 0000000..8337d69 --- /dev/null +++ b/examples/win32_api/examples.dsw @@ -0,0 +1,761 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "aa_demo"=".\aa_demo\aa_demo.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "aa_test"=".\aa_test\aa_test.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "alpha_gradient"=".\alpha_gradient\alpha_gradient.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "alpha_mask"=".\alpha_mask\alpha_mask.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "alpha_mask2"=".\alpha_mask2\alpha_mask2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "alpha_mask3"=".\alpha_mask3\alpha_mask3.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "bezier_div"=".\bezier_div\bezier_div.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "blend_color"=".\blend_color\blend_color.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "blur"=".\blur\blur.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "bspline"=".\bspline\bspline.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "circles"=".\circles\circles.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "component_rendering"=".\component_rendering\component_rendering.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "compositing"=".\compositing\compositing.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "compositing2"=".\compositing2\compositing2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "conv_contour"=".\conv_contour\conv_contour.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "conv_dash_marker"=".\conv_dash_marker\conv_dash_marker.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "conv_stroke"=".\conv_stroke\conv_stroke.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "distortions"=".\distortions\distortions.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "flash_rasterizer"=".\flash_rasterizer\flash_rasterizer.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "flash_rasterizer2"=".\flash_rasterizer2\flash_rasterizer2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gamma_correction"=".\gamma_correction\gamma_correction.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gamma_ctrl"=".\gamma_ctrl\gamma_ctrl.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gamma_tuner"=".\gamma_tuner\gamma_tuner.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gouraud"=".\gouraud\gouraud.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gouraud_mesh"=".\gouraud_mesh\gouraud_mesh.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gpc_test"=".\gpc_test\gpc_test.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gradient_focal"=".\gradient_focal\gradient_focal.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "gradients"=".\gradients\gradients.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "graph_test"=".\graph_test\graph_test.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "idea"=".\idea\idea.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "image1"=".\image1\image1.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "image_alpha"=".\image_alpha\image_alpha.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "image_filters"=".\image_filters\image_filters.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "image_filters2"=".\image_filters2\image_filters2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "image_fltr_graph"=".\image_fltr_graph\image_fltr_graph.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "image_perspective"=".\image_perspective\image_perspective.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "image_resample"=".\image_resample\image_resample.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "image_transforms"=".\image_transforms\image_transforms.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "line_patterns"=".\line_patterns\line_patterns.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "line_patterns_clip"=".\line_patterns_clip\line_patterns_clip.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "lion"=".\lion\lion.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "lion_lens"=".\lion_lens\lion_lens.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "lion_outline"=".\lion_outline\lion_outline.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "mol_view"=".\mol_view\mol_view.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "multi_clip"=".\multi_clip\multi_clip.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "pattern_fill"=".\pattern_fill\pattern_fill.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "pattern_perspective"=".\pattern_perspective\pattern_perspective.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "perspective"=".\perspective\perspective.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "polymorphic_renderer"=".\polymorphic_renderer\polymorphic_renderer.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "pure_api"=".\pure_api\pure_api.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "raster_text"=".\raster_text\raster_text.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "rasterizer_compound"=".\rasterizer_compound\rasterizer_compound.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "rasterizers"=".\rasterizers\rasterizers.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "rasterizers2"=".\rasterizers2\rasterizers2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "rounded_rect"=".\rounded_rect\rounded_rect.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "scanline_boolean"=".\scanline_boolean\scanline_boolean.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "scanline_boolean2"=".\scanline_boolean2\scanline_boolean2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "simple_blur"=".\simple_blur\simple_blur.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "trans_curve1"=".\trans_curve1\trans_curve1.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "trans_curve2"=".\trans_curve2\trans_curve2.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "trans_polar"=".\trans_polar\trans_polar.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "truetype_test"=".\truetype_test\truetype_test.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/examples.sln b/examples/win32_api/examples.sln new file mode 100644 index 0000000..79d724f --- /dev/null +++ b/examples/win32_api/examples.sln @@ -0,0 +1,744 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aa_demo", "aa_demo\aa_demo.vcxproj", "{B0426FB2-76DF-32F0-0774-4A6998FC1E54}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aa_test", "aa_test\aa_test.vcxproj", "{DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alpha_gradient", "alpha_gradient\alpha_gradient.vcxproj", "{73275357-2B4C-6183-1E18-C8C41B62F6DF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alpha_mask", "alpha_mask\alpha_mask.vcxproj", "{37C8795F-976D-BCF8-639C-FF2DC2AC17CE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alpha_mask2", "alpha_mask2\alpha_mask2.vcxproj", "{32435053-471C-9795-E555-A6BD34E3B70A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alpha_mask3", "alpha_mask3\alpha_mask3.vcxproj", "{37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bezier_div", "bezier_div\bezier_div.vcxproj", "{1C36D677-7993-4E51-2773-B4094FB8EE2A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blend_color", "blend_color\blend_color.vcxproj", "{A9DD4081-1935-AF41-62EF-B23E97832EC7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "blur", "blur\blur.vcxproj", "{C9681374-4905-6476-F859-F756197FCB9F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bspline", "bspline\bspline.vcxproj", "{369F608F-B992-7E21-FF16-CAC95B52382F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "circles", "circles\circles.vcxproj", "{ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "component_rendering", "component_rendering\component_rendering.vcxproj", "{E67DB44E-2CE0-5DC6-66A0-66146D7176DE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "compositing", "compositing\compositing.vcxproj", "{79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "compositing2", "compositing2\compositing2.vcxproj", "{9D610545-E382-D6FB-7D74-8DD26086BF0E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conv_contour", "conv_contour\conv_contour.vcxproj", "{762ECE3C-F322-02D1-512A-C903F140FD90}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conv_dash_marker", "conv_dash_marker\conv_dash_marker.vcxproj", "{A65DC652-88CF-A922-1AB4-DE39386D66B2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "conv_stroke", "conv_stroke\conv_stroke.vcxproj", "{A6669230-ECD1-D652-159F-08DCE667B630}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "distortions", "distortions\distortions.vcxproj", "{080665EE-6049-7077-64BA-191B30EA7756}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flash_rasterizer", "flash_rasterizer\flash_rasterizer.vcxproj", "{5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flash_rasterizer2", "flash_rasterizer2\flash_rasterizer2.vcxproj", "{D873A8A1-683A-B8CA-DAC8-E17948138BAE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gamma_correction", "gamma_correction\gamma_correction.vcxproj", "{CB620C3E-E1AE-7256-A156-3D7DA1F6B389}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gamma_ctrl", "gamma_ctrl\gamma_ctrl.vcxproj", "{3275483B-428E-AA1F-FCA7-79A473B09309}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gamma_tuner", "gamma_tuner\gamma_tuner.vcxproj", "{6590D1BE-BEF8-6724-0334-3E729C64CC7A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gouraud", "gouraud\gouraud.vcxproj", "{A4D74496-7313-3123-B26C-29B3C16D5ED6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gouraud_mesh", "gouraud_mesh\gouraud_mesh.vcxproj", "{725B73C0-F3C8-D6E8-53D0-4C2418122ADB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpc_test", "gpc_test\gpc_test.vcxproj", "{DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gradient_focal", "gradient_focal\gradient_focal.vcxproj", "{E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gradients", "gradients\gradients.vcxproj", "{44FB9161-7404-16D4-B571-5CB85384B609}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "graph_test", "graph_test\graph_test.vcxproj", "{9A22718A-2B37-9BB2-3064-E04B5B92D1E7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "idea", "idea\idea.vcxproj", "{46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image1", "image1\image1.vcxproj", "{A58FEE69-867D-1FF4-62BE-6F58020624D0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_alpha", "image_alpha\image_alpha.vcxproj", "{EC41EC41-BEC3-B108-A96C-304F123869D3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_filters", "image_filters\image_filters.vcxproj", "{FBFDF907-772D-20C1-B966-7AA299DEE301}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_filters2", "image_filters2\image_filters2.vcxproj", "{67D784F4-AE57-86EF-85CB-9EC6CADFF616}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_fltr_graph", "image_fltr_graph\image_fltr_graph.vcxproj", "{7CB77339-97A9-1507-BF82-11BD57A3733B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_perspective", "image_perspective\image_perspective.vcxproj", "{CCCB62D2-F473-1858-6280-12EB5371C317}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_resample", "image_resample\image_resample.vcxproj", "{FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "image_transforms", "image_transforms\image_transforms.vcxproj", "{AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "line_patterns", "line_patterns\line_patterns.vcxproj", "{1AC06016-EA58-2079-0D9E-E85B198188B6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "line_patterns_clip", "line_patterns_clip\line_patterns_clip.vcxproj", "{B7F52AEF-C4E7-049C-3C28-902A52C24D9D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lion", "lion\lion.vcxproj", "{636E09D4-0678-A349-3C54-B4F5D29D2440}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lion_lens", "lion_lens\lion_lens.vcxproj", "{F61620DA-B261-3836-F808-29991B8EB622}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lion_outline", "lion_outline\lion_outline.vcxproj", "{1C282CA7-6080-A229-B4BD-22BFC1E56A0D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mol_view", "mol_view\mol_view.vcxproj", "{DA6B065B-8BD3-ADCD-28D7-D4BB41003200}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_clip", "multi_clip\multi_clip.vcxproj", "{7784A618-B98E-55A1-EB91-92B1BACE7C30}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pattern_fill", "pattern_fill\pattern_fill.vcxproj", "{4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pattern_perspective", "pattern_perspective\pattern_perspective.vcxproj", "{48F212BB-AAEA-A634-2A87-90A48D73486E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "perspective", "perspective\perspective.vcxproj", "{9E72EC9B-93D8-D749-88D7-25742B73A303}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "polymorphic_renderer", "polymorphic_renderer\polymorphic_renderer.vcxproj", "{01580078-9E68-4ECA-9C68-334F1CF215C2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pure_api", "pure_api\pure_api.vcxproj", "{B1879B0F-4ACA-B943-3474-E584D659362F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raster_text", "raster_text\raster_text.vcxproj", "{EBCB363B-3793-507F-559E-30FF760ACB03}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rasterizer_compound", "rasterizer_compound\rasterizer_compound.vcxproj", "{CEA11124-03C2-06D5-39DC-9E9866B05B99}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rasterizers", "rasterizers\rasterizers.vcxproj", "{D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rasterizers2", "rasterizers2\rasterizers2.vcxproj", "{62F9D117-6886-87C3-B719-D59791638994}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rounded_rect", "rounded_rect\rounded_rect.vcxproj", "{3DDFB788-8751-3001-00EF-B3E42C09FFD1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scanline_boolean", "scanline_boolean\scanline_boolean.vcxproj", "{FAA982B0-05C2-6440-9EC2-C0032CE56B4F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scanline_boolean2", "scanline_boolean2\scanline_boolean2.vcxproj", "{88AC3D30-0084-D856-77C4-AB749ED4FFAA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_blur", "simple_blur\simple_blur.vcxproj", "{F2CDDE95-2042-51DD-50AF-8CB33C91A363}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trans_curve1", "trans_curve1\trans_curve1.vcxproj", "{04837E0B-4CCF-A526-E9EC-E78EA4640AEB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trans_curve2", "trans_curve2\trans_curve2.vcxproj", "{ABE48445-AD58-FBBA-6693-E5B8701BC6CF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trans_polar", "trans_polar\trans_polar.vcxproj", "{BF39ECC1-095F-E7FB-BBB6-563332B4470F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "truetype_test", "truetype_test\truetype_test.vcxproj", "{EA706565-3FDB-5B31-6C36-C27C2AD257EF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "agg2d_demo", "agg2d_demo\agg2d_demo.vcxproj", "{6015656F-2EE0-42FD-9EE3-DE54A429EE00}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "line_thickness", "line_thickness\line_thickness.vcxproj", "{5E787227-E9A9-4839-AD18-6CDC16C6D1A6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "svg_test", "svg_test\svg_test.vcxproj", "{6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pattern_resample", "pattern_resample\pattern_resample.vcxproj", "{A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + Template|Win32 = Template|Win32 + Template|x64 = Template|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B0426FB2-76DF-32F0-0774-4A6998FC1E54}.Debug|Win32.ActiveCfg = Debug|Win32 + {B0426FB2-76DF-32F0-0774-4A6998FC1E54}.Debug|Win32.Build.0 = Debug|Win32 + {B0426FB2-76DF-32F0-0774-4A6998FC1E54}.Debug|x64.ActiveCfg = Debug|Win32 + {B0426FB2-76DF-32F0-0774-4A6998FC1E54}.Release|Win32.ActiveCfg = Release|Win32 + {B0426FB2-76DF-32F0-0774-4A6998FC1E54}.Release|Win32.Build.0 = Release|Win32 + {B0426FB2-76DF-32F0-0774-4A6998FC1E54}.Release|x64.ActiveCfg = Release|Win32 + {B0426FB2-76DF-32F0-0774-4A6998FC1E54}.Template|Win32.ActiveCfg = Release|Win32 + {B0426FB2-76DF-32F0-0774-4A6998FC1E54}.Template|Win32.Build.0 = Release|Win32 + {B0426FB2-76DF-32F0-0774-4A6998FC1E54}.Template|x64.ActiveCfg = Release|Win32 + {DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}.Debug|Win32.ActiveCfg = Debug|Win32 + {DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}.Debug|Win32.Build.0 = Debug|Win32 + {DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}.Debug|x64.ActiveCfg = Debug|Win32 + {DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}.Release|Win32.ActiveCfg = Release|Win32 + {DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}.Release|Win32.Build.0 = Release|Win32 + {DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}.Release|x64.ActiveCfg = Release|Win32 + {DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}.Template|Win32.ActiveCfg = Template|Win32 + {DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}.Template|Win32.Build.0 = Template|Win32 + {DE9F0AFF-8938-2F01-3DC0-1D50A2E6AFE6}.Template|x64.ActiveCfg = Template|Win32 + {73275357-2B4C-6183-1E18-C8C41B62F6DF}.Debug|Win32.ActiveCfg = Debug|Win32 + {73275357-2B4C-6183-1E18-C8C41B62F6DF}.Debug|Win32.Build.0 = Debug|Win32 + {73275357-2B4C-6183-1E18-C8C41B62F6DF}.Debug|x64.ActiveCfg = Debug|Win32 + {73275357-2B4C-6183-1E18-C8C41B62F6DF}.Release|Win32.ActiveCfg = Release|Win32 + {73275357-2B4C-6183-1E18-C8C41B62F6DF}.Release|Win32.Build.0 = Release|Win32 + {73275357-2B4C-6183-1E18-C8C41B62F6DF}.Release|x64.ActiveCfg = Release|Win32 + {73275357-2B4C-6183-1E18-C8C41B62F6DF}.Template|Win32.ActiveCfg = Template|Win32 + {73275357-2B4C-6183-1E18-C8C41B62F6DF}.Template|Win32.Build.0 = Template|Win32 + {73275357-2B4C-6183-1E18-C8C41B62F6DF}.Template|x64.ActiveCfg = Template|Win32 + {37C8795F-976D-BCF8-639C-FF2DC2AC17CE}.Debug|Win32.ActiveCfg = Debug|Win32 + {37C8795F-976D-BCF8-639C-FF2DC2AC17CE}.Debug|Win32.Build.0 = Debug|Win32 + {37C8795F-976D-BCF8-639C-FF2DC2AC17CE}.Debug|x64.ActiveCfg = Debug|Win32 + {37C8795F-976D-BCF8-639C-FF2DC2AC17CE}.Release|Win32.ActiveCfg = Release|Win32 + {37C8795F-976D-BCF8-639C-FF2DC2AC17CE}.Release|Win32.Build.0 = Release|Win32 + {37C8795F-976D-BCF8-639C-FF2DC2AC17CE}.Release|x64.ActiveCfg = Release|Win32 + {37C8795F-976D-BCF8-639C-FF2DC2AC17CE}.Template|Win32.ActiveCfg = Template|Win32 + {37C8795F-976D-BCF8-639C-FF2DC2AC17CE}.Template|Win32.Build.0 = Template|Win32 + {37C8795F-976D-BCF8-639C-FF2DC2AC17CE}.Template|x64.ActiveCfg = Template|Win32 + {32435053-471C-9795-E555-A6BD34E3B70A}.Debug|Win32.ActiveCfg = Debug|Win32 + {32435053-471C-9795-E555-A6BD34E3B70A}.Debug|Win32.Build.0 = Debug|Win32 + {32435053-471C-9795-E555-A6BD34E3B70A}.Debug|x64.ActiveCfg = Debug|Win32 + {32435053-471C-9795-E555-A6BD34E3B70A}.Release|Win32.ActiveCfg = Release|Win32 + {32435053-471C-9795-E555-A6BD34E3B70A}.Release|Win32.Build.0 = Release|Win32 + {32435053-471C-9795-E555-A6BD34E3B70A}.Release|x64.ActiveCfg = Release|Win32 + {32435053-471C-9795-E555-A6BD34E3B70A}.Template|Win32.ActiveCfg = Template|Win32 + {32435053-471C-9795-E555-A6BD34E3B70A}.Template|Win32.Build.0 = Template|Win32 + {32435053-471C-9795-E555-A6BD34E3B70A}.Template|x64.ActiveCfg = Template|Win32 + {37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}.Debug|Win32.ActiveCfg = Debug|Win32 + {37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}.Debug|Win32.Build.0 = Debug|Win32 + {37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}.Debug|x64.ActiveCfg = Debug|Win32 + {37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}.Release|Win32.ActiveCfg = Release|Win32 + {37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}.Release|Win32.Build.0 = Release|Win32 + {37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}.Release|x64.ActiveCfg = Release|Win32 + {37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}.Template|Win32.ActiveCfg = Template|Win32 + {37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}.Template|Win32.Build.0 = Template|Win32 + {37F06EF4-64D7-03C9-5DA5-83F8648CD9BE}.Template|x64.ActiveCfg = Template|Win32 + {1C36D677-7993-4E51-2773-B4094FB8EE2A}.Debug|Win32.ActiveCfg = Debug|Win32 + {1C36D677-7993-4E51-2773-B4094FB8EE2A}.Debug|Win32.Build.0 = Debug|Win32 + {1C36D677-7993-4E51-2773-B4094FB8EE2A}.Debug|x64.ActiveCfg = Debug|Win32 + {1C36D677-7993-4E51-2773-B4094FB8EE2A}.Release|Win32.ActiveCfg = Release|Win32 + {1C36D677-7993-4E51-2773-B4094FB8EE2A}.Release|Win32.Build.0 = Release|Win32 + {1C36D677-7993-4E51-2773-B4094FB8EE2A}.Release|x64.ActiveCfg = Release|Win32 + {1C36D677-7993-4E51-2773-B4094FB8EE2A}.Template|Win32.ActiveCfg = Template|Win32 + {1C36D677-7993-4E51-2773-B4094FB8EE2A}.Template|Win32.Build.0 = Template|Win32 + {1C36D677-7993-4E51-2773-B4094FB8EE2A}.Template|x64.ActiveCfg = Template|Win32 + {A9DD4081-1935-AF41-62EF-B23E97832EC7}.Debug|Win32.ActiveCfg = Debug|Win32 + {A9DD4081-1935-AF41-62EF-B23E97832EC7}.Debug|Win32.Build.0 = Debug|Win32 + {A9DD4081-1935-AF41-62EF-B23E97832EC7}.Debug|x64.ActiveCfg = Debug|Win32 + {A9DD4081-1935-AF41-62EF-B23E97832EC7}.Release|Win32.ActiveCfg = Release|Win32 + {A9DD4081-1935-AF41-62EF-B23E97832EC7}.Release|Win32.Build.0 = Release|Win32 + {A9DD4081-1935-AF41-62EF-B23E97832EC7}.Release|x64.ActiveCfg = Release|Win32 + {A9DD4081-1935-AF41-62EF-B23E97832EC7}.Template|Win32.ActiveCfg = Template|Win32 + {A9DD4081-1935-AF41-62EF-B23E97832EC7}.Template|Win32.Build.0 = Template|Win32 + {A9DD4081-1935-AF41-62EF-B23E97832EC7}.Template|x64.ActiveCfg = Template|Win32 + {C9681374-4905-6476-F859-F756197FCB9F}.Debug|Win32.ActiveCfg = Debug|Win32 + {C9681374-4905-6476-F859-F756197FCB9F}.Debug|Win32.Build.0 = Debug|Win32 + {C9681374-4905-6476-F859-F756197FCB9F}.Debug|x64.ActiveCfg = Debug|Win32 + {C9681374-4905-6476-F859-F756197FCB9F}.Release|Win32.ActiveCfg = Release|Win32 + {C9681374-4905-6476-F859-F756197FCB9F}.Release|Win32.Build.0 = Release|Win32 + {C9681374-4905-6476-F859-F756197FCB9F}.Release|x64.ActiveCfg = Release|Win32 + {C9681374-4905-6476-F859-F756197FCB9F}.Template|Win32.ActiveCfg = Template|Win32 + {C9681374-4905-6476-F859-F756197FCB9F}.Template|Win32.Build.0 = Template|Win32 + {C9681374-4905-6476-F859-F756197FCB9F}.Template|x64.ActiveCfg = Template|Win32 + {369F608F-B992-7E21-FF16-CAC95B52382F}.Debug|Win32.ActiveCfg = Debug|Win32 + {369F608F-B992-7E21-FF16-CAC95B52382F}.Debug|Win32.Build.0 = Debug|Win32 + {369F608F-B992-7E21-FF16-CAC95B52382F}.Debug|x64.ActiveCfg = Debug|Win32 + {369F608F-B992-7E21-FF16-CAC95B52382F}.Release|Win32.ActiveCfg = Release|Win32 + {369F608F-B992-7E21-FF16-CAC95B52382F}.Release|Win32.Build.0 = Release|Win32 + {369F608F-B992-7E21-FF16-CAC95B52382F}.Release|x64.ActiveCfg = Release|Win32 + {369F608F-B992-7E21-FF16-CAC95B52382F}.Template|Win32.ActiveCfg = Template|Win32 + {369F608F-B992-7E21-FF16-CAC95B52382F}.Template|Win32.Build.0 = Template|Win32 + {369F608F-B992-7E21-FF16-CAC95B52382F}.Template|x64.ActiveCfg = Template|Win32 + {ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}.Debug|Win32.ActiveCfg = Debug|Win32 + {ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}.Debug|Win32.Build.0 = Debug|Win32 + {ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}.Debug|x64.ActiveCfg = Debug|Win32 + {ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}.Release|Win32.ActiveCfg = Release|Win32 + {ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}.Release|Win32.Build.0 = Release|Win32 + {ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}.Release|x64.ActiveCfg = Release|Win32 + {ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}.Template|Win32.ActiveCfg = Template|Win32 + {ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}.Template|Win32.Build.0 = Template|Win32 + {ADE93497-E48F-3B14-616F-A1AD6A1FA5E0}.Template|x64.ActiveCfg = Template|Win32 + {E67DB44E-2CE0-5DC6-66A0-66146D7176DE}.Debug|Win32.ActiveCfg = Debug|Win32 + {E67DB44E-2CE0-5DC6-66A0-66146D7176DE}.Debug|Win32.Build.0 = Debug|Win32 + {E67DB44E-2CE0-5DC6-66A0-66146D7176DE}.Debug|x64.ActiveCfg = Debug|Win32 + {E67DB44E-2CE0-5DC6-66A0-66146D7176DE}.Release|Win32.ActiveCfg = Release|Win32 + {E67DB44E-2CE0-5DC6-66A0-66146D7176DE}.Release|Win32.Build.0 = Release|Win32 + {E67DB44E-2CE0-5DC6-66A0-66146D7176DE}.Release|x64.ActiveCfg = Release|Win32 + {E67DB44E-2CE0-5DC6-66A0-66146D7176DE}.Template|Win32.ActiveCfg = Template|Win32 + {E67DB44E-2CE0-5DC6-66A0-66146D7176DE}.Template|Win32.Build.0 = Template|Win32 + {E67DB44E-2CE0-5DC6-66A0-66146D7176DE}.Template|x64.ActiveCfg = Template|Win32 + {79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}.Debug|Win32.ActiveCfg = Debug|Win32 + {79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}.Debug|Win32.Build.0 = Debug|Win32 + {79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}.Debug|x64.ActiveCfg = Debug|Win32 + {79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}.Release|Win32.ActiveCfg = Release|Win32 + {79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}.Release|Win32.Build.0 = Release|Win32 + {79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}.Release|x64.ActiveCfg = Release|Win32 + {79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}.Template|Win32.ActiveCfg = Template|Win32 + {79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}.Template|Win32.Build.0 = Template|Win32 + {79BDAF62-B93A-1D14-3B79-86CE3EA7A9FF}.Template|x64.ActiveCfg = Template|Win32 + {9D610545-E382-D6FB-7D74-8DD26086BF0E}.Debug|Win32.ActiveCfg = Debug|Win32 + {9D610545-E382-D6FB-7D74-8DD26086BF0E}.Debug|Win32.Build.0 = Debug|Win32 + {9D610545-E382-D6FB-7D74-8DD26086BF0E}.Debug|x64.ActiveCfg = Debug|Win32 + {9D610545-E382-D6FB-7D74-8DD26086BF0E}.Release|Win32.ActiveCfg = Release|Win32 + {9D610545-E382-D6FB-7D74-8DD26086BF0E}.Release|Win32.Build.0 = Release|Win32 + {9D610545-E382-D6FB-7D74-8DD26086BF0E}.Release|x64.ActiveCfg = Release|Win32 + {9D610545-E382-D6FB-7D74-8DD26086BF0E}.Template|Win32.ActiveCfg = Template|Win32 + {9D610545-E382-D6FB-7D74-8DD26086BF0E}.Template|Win32.Build.0 = Template|Win32 + {9D610545-E382-D6FB-7D74-8DD26086BF0E}.Template|x64.ActiveCfg = Template|Win32 + {762ECE3C-F322-02D1-512A-C903F140FD90}.Debug|Win32.ActiveCfg = Debug|Win32 + {762ECE3C-F322-02D1-512A-C903F140FD90}.Debug|Win32.Build.0 = Debug|Win32 + {762ECE3C-F322-02D1-512A-C903F140FD90}.Debug|x64.ActiveCfg = Debug|Win32 + {762ECE3C-F322-02D1-512A-C903F140FD90}.Release|Win32.ActiveCfg = Release|Win32 + {762ECE3C-F322-02D1-512A-C903F140FD90}.Release|Win32.Build.0 = Release|Win32 + {762ECE3C-F322-02D1-512A-C903F140FD90}.Release|x64.ActiveCfg = Release|Win32 + {762ECE3C-F322-02D1-512A-C903F140FD90}.Template|Win32.ActiveCfg = Template|Win32 + {762ECE3C-F322-02D1-512A-C903F140FD90}.Template|Win32.Build.0 = Template|Win32 + {762ECE3C-F322-02D1-512A-C903F140FD90}.Template|x64.ActiveCfg = Template|Win32 + {A65DC652-88CF-A922-1AB4-DE39386D66B2}.Debug|Win32.ActiveCfg = Debug|Win32 + {A65DC652-88CF-A922-1AB4-DE39386D66B2}.Debug|Win32.Build.0 = Debug|Win32 + {A65DC652-88CF-A922-1AB4-DE39386D66B2}.Debug|x64.ActiveCfg = Debug|Win32 + {A65DC652-88CF-A922-1AB4-DE39386D66B2}.Release|Win32.ActiveCfg = Release|Win32 + {A65DC652-88CF-A922-1AB4-DE39386D66B2}.Release|Win32.Build.0 = Release|Win32 + {A65DC652-88CF-A922-1AB4-DE39386D66B2}.Release|x64.ActiveCfg = Release|Win32 + {A65DC652-88CF-A922-1AB4-DE39386D66B2}.Template|Win32.ActiveCfg = Template|Win32 + {A65DC652-88CF-A922-1AB4-DE39386D66B2}.Template|Win32.Build.0 = Template|Win32 + {A65DC652-88CF-A922-1AB4-DE39386D66B2}.Template|x64.ActiveCfg = Template|Win32 + {A6669230-ECD1-D652-159F-08DCE667B630}.Debug|Win32.ActiveCfg = Debug|Win32 + {A6669230-ECD1-D652-159F-08DCE667B630}.Debug|Win32.Build.0 = Debug|Win32 + {A6669230-ECD1-D652-159F-08DCE667B630}.Debug|x64.ActiveCfg = Debug|Win32 + {A6669230-ECD1-D652-159F-08DCE667B630}.Release|Win32.ActiveCfg = Release|Win32 + {A6669230-ECD1-D652-159F-08DCE667B630}.Release|Win32.Build.0 = Release|Win32 + {A6669230-ECD1-D652-159F-08DCE667B630}.Release|x64.ActiveCfg = Release|Win32 + {A6669230-ECD1-D652-159F-08DCE667B630}.Template|Win32.ActiveCfg = Template|Win32 + {A6669230-ECD1-D652-159F-08DCE667B630}.Template|Win32.Build.0 = Template|Win32 + {A6669230-ECD1-D652-159F-08DCE667B630}.Template|x64.ActiveCfg = Template|Win32 + {080665EE-6049-7077-64BA-191B30EA7756}.Debug|Win32.ActiveCfg = Debug|Win32 + {080665EE-6049-7077-64BA-191B30EA7756}.Debug|Win32.Build.0 = Debug|Win32 + {080665EE-6049-7077-64BA-191B30EA7756}.Debug|x64.ActiveCfg = Debug|Win32 + {080665EE-6049-7077-64BA-191B30EA7756}.Release|Win32.ActiveCfg = Release|Win32 + {080665EE-6049-7077-64BA-191B30EA7756}.Release|Win32.Build.0 = Release|Win32 + {080665EE-6049-7077-64BA-191B30EA7756}.Release|x64.ActiveCfg = Release|Win32 + {080665EE-6049-7077-64BA-191B30EA7756}.Template|Win32.ActiveCfg = Template|Win32 + {080665EE-6049-7077-64BA-191B30EA7756}.Template|Win32.Build.0 = Template|Win32 + {080665EE-6049-7077-64BA-191B30EA7756}.Template|x64.ActiveCfg = Template|Win32 + {5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}.Debug|Win32.ActiveCfg = Debug|Win32 + {5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}.Debug|Win32.Build.0 = Debug|Win32 + {5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}.Debug|x64.ActiveCfg = Debug|Win32 + {5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}.Release|Win32.ActiveCfg = Release|Win32 + {5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}.Release|Win32.Build.0 = Release|Win32 + {5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}.Release|x64.ActiveCfg = Release|Win32 + {5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}.Template|Win32.ActiveCfg = Template|Win32 + {5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}.Template|Win32.Build.0 = Template|Win32 + {5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}.Template|x64.ActiveCfg = Template|Win32 + {D873A8A1-683A-B8CA-DAC8-E17948138BAE}.Debug|Win32.ActiveCfg = Debug|Win32 + {D873A8A1-683A-B8CA-DAC8-E17948138BAE}.Debug|Win32.Build.0 = Debug|Win32 + {D873A8A1-683A-B8CA-DAC8-E17948138BAE}.Debug|x64.ActiveCfg = Debug|Win32 + {D873A8A1-683A-B8CA-DAC8-E17948138BAE}.Release|Win32.ActiveCfg = Release|Win32 + {D873A8A1-683A-B8CA-DAC8-E17948138BAE}.Release|Win32.Build.0 = Release|Win32 + {D873A8A1-683A-B8CA-DAC8-E17948138BAE}.Release|x64.ActiveCfg = Release|Win32 + {D873A8A1-683A-B8CA-DAC8-E17948138BAE}.Template|Win32.ActiveCfg = Template|Win32 + {D873A8A1-683A-B8CA-DAC8-E17948138BAE}.Template|Win32.Build.0 = Template|Win32 + {D873A8A1-683A-B8CA-DAC8-E17948138BAE}.Template|x64.ActiveCfg = Template|Win32 + {CB620C3E-E1AE-7256-A156-3D7DA1F6B389}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB620C3E-E1AE-7256-A156-3D7DA1F6B389}.Debug|Win32.Build.0 = Debug|Win32 + {CB620C3E-E1AE-7256-A156-3D7DA1F6B389}.Debug|x64.ActiveCfg = Debug|Win32 + {CB620C3E-E1AE-7256-A156-3D7DA1F6B389}.Release|Win32.ActiveCfg = Release|Win32 + {CB620C3E-E1AE-7256-A156-3D7DA1F6B389}.Release|Win32.Build.0 = Release|Win32 + {CB620C3E-E1AE-7256-A156-3D7DA1F6B389}.Release|x64.ActiveCfg = Release|Win32 + {CB620C3E-E1AE-7256-A156-3D7DA1F6B389}.Template|Win32.ActiveCfg = Template|Win32 + {CB620C3E-E1AE-7256-A156-3D7DA1F6B389}.Template|Win32.Build.0 = Template|Win32 + {CB620C3E-E1AE-7256-A156-3D7DA1F6B389}.Template|x64.ActiveCfg = Template|Win32 + {3275483B-428E-AA1F-FCA7-79A473B09309}.Debug|Win32.ActiveCfg = Debug|Win32 + {3275483B-428E-AA1F-FCA7-79A473B09309}.Debug|Win32.Build.0 = Debug|Win32 + {3275483B-428E-AA1F-FCA7-79A473B09309}.Debug|x64.ActiveCfg = Debug|Win32 + {3275483B-428E-AA1F-FCA7-79A473B09309}.Release|Win32.ActiveCfg = Release|Win32 + {3275483B-428E-AA1F-FCA7-79A473B09309}.Release|Win32.Build.0 = Release|Win32 + {3275483B-428E-AA1F-FCA7-79A473B09309}.Release|x64.ActiveCfg = Release|Win32 + {3275483B-428E-AA1F-FCA7-79A473B09309}.Template|Win32.ActiveCfg = Template|Win32 + {3275483B-428E-AA1F-FCA7-79A473B09309}.Template|Win32.Build.0 = Template|Win32 + {3275483B-428E-AA1F-FCA7-79A473B09309}.Template|x64.ActiveCfg = Template|Win32 + {6590D1BE-BEF8-6724-0334-3E729C64CC7A}.Debug|Win32.ActiveCfg = Debug|Win32 + {6590D1BE-BEF8-6724-0334-3E729C64CC7A}.Debug|Win32.Build.0 = Debug|Win32 + {6590D1BE-BEF8-6724-0334-3E729C64CC7A}.Debug|x64.ActiveCfg = Debug|Win32 + {6590D1BE-BEF8-6724-0334-3E729C64CC7A}.Release|Win32.ActiveCfg = Release|Win32 + {6590D1BE-BEF8-6724-0334-3E729C64CC7A}.Release|Win32.Build.0 = Release|Win32 + {6590D1BE-BEF8-6724-0334-3E729C64CC7A}.Release|x64.ActiveCfg = Release|Win32 + {6590D1BE-BEF8-6724-0334-3E729C64CC7A}.Template|Win32.ActiveCfg = Template|Win32 + {6590D1BE-BEF8-6724-0334-3E729C64CC7A}.Template|Win32.Build.0 = Template|Win32 + {6590D1BE-BEF8-6724-0334-3E729C64CC7A}.Template|x64.ActiveCfg = Template|Win32 + {A4D74496-7313-3123-B26C-29B3C16D5ED6}.Debug|Win32.ActiveCfg = Debug|Win32 + {A4D74496-7313-3123-B26C-29B3C16D5ED6}.Debug|Win32.Build.0 = Debug|Win32 + {A4D74496-7313-3123-B26C-29B3C16D5ED6}.Debug|x64.ActiveCfg = Debug|Win32 + {A4D74496-7313-3123-B26C-29B3C16D5ED6}.Release|Win32.ActiveCfg = Release|Win32 + {A4D74496-7313-3123-B26C-29B3C16D5ED6}.Release|Win32.Build.0 = Release|Win32 + {A4D74496-7313-3123-B26C-29B3C16D5ED6}.Release|x64.ActiveCfg = Release|Win32 + {A4D74496-7313-3123-B26C-29B3C16D5ED6}.Template|Win32.ActiveCfg = Template|Win32 + {A4D74496-7313-3123-B26C-29B3C16D5ED6}.Template|Win32.Build.0 = Template|Win32 + {A4D74496-7313-3123-B26C-29B3C16D5ED6}.Template|x64.ActiveCfg = Template|Win32 + {725B73C0-F3C8-D6E8-53D0-4C2418122ADB}.Debug|Win32.ActiveCfg = Debug|Win32 + {725B73C0-F3C8-D6E8-53D0-4C2418122ADB}.Debug|Win32.Build.0 = Debug|Win32 + {725B73C0-F3C8-D6E8-53D0-4C2418122ADB}.Debug|x64.ActiveCfg = Debug|Win32 + {725B73C0-F3C8-D6E8-53D0-4C2418122ADB}.Release|Win32.ActiveCfg = Release|Win32 + {725B73C0-F3C8-D6E8-53D0-4C2418122ADB}.Release|Win32.Build.0 = Release|Win32 + {725B73C0-F3C8-D6E8-53D0-4C2418122ADB}.Release|x64.ActiveCfg = Release|Win32 + {725B73C0-F3C8-D6E8-53D0-4C2418122ADB}.Template|Win32.ActiveCfg = Template|Win32 + {725B73C0-F3C8-D6E8-53D0-4C2418122ADB}.Template|Win32.Build.0 = Template|Win32 + {725B73C0-F3C8-D6E8-53D0-4C2418122ADB}.Template|x64.ActiveCfg = Template|Win32 + {DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}.Debug|Win32.ActiveCfg = Debug|Win32 + {DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}.Debug|Win32.Build.0 = Debug|Win32 + {DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}.Debug|x64.ActiveCfg = Debug|Win32 + {DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}.Release|Win32.ActiveCfg = Release|Win32 + {DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}.Release|Win32.Build.0 = Release|Win32 + {DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}.Release|x64.ActiveCfg = Release|Win32 + {DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}.Template|Win32.ActiveCfg = Template|Win32 + {DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}.Template|Win32.Build.0 = Template|Win32 + {DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}.Template|x64.ActiveCfg = Template|Win32 + {E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}.Debug|Win32.ActiveCfg = Debug|Win32 + {E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}.Debug|Win32.Build.0 = Debug|Win32 + {E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}.Debug|x64.ActiveCfg = Debug|Win32 + {E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}.Release|Win32.ActiveCfg = Release|Win32 + {E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}.Release|Win32.Build.0 = Release|Win32 + {E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}.Release|x64.ActiveCfg = Release|Win32 + {E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}.Template|Win32.ActiveCfg = Template|Win32 + {E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}.Template|Win32.Build.0 = Template|Win32 + {E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}.Template|x64.ActiveCfg = Template|Win32 + {44FB9161-7404-16D4-B571-5CB85384B609}.Debug|Win32.ActiveCfg = Debug|Win32 + {44FB9161-7404-16D4-B571-5CB85384B609}.Debug|Win32.Build.0 = Debug|Win32 + {44FB9161-7404-16D4-B571-5CB85384B609}.Debug|x64.ActiveCfg = Debug|Win32 + {44FB9161-7404-16D4-B571-5CB85384B609}.Release|Win32.ActiveCfg = Release|Win32 + {44FB9161-7404-16D4-B571-5CB85384B609}.Release|Win32.Build.0 = Release|Win32 + {44FB9161-7404-16D4-B571-5CB85384B609}.Release|x64.ActiveCfg = Release|Win32 + {44FB9161-7404-16D4-B571-5CB85384B609}.Template|Win32.ActiveCfg = Template|Win32 + {44FB9161-7404-16D4-B571-5CB85384B609}.Template|Win32.Build.0 = Template|Win32 + {44FB9161-7404-16D4-B571-5CB85384B609}.Template|x64.ActiveCfg = Template|Win32 + {9A22718A-2B37-9BB2-3064-E04B5B92D1E7}.Debug|Win32.ActiveCfg = Debug|Win32 + {9A22718A-2B37-9BB2-3064-E04B5B92D1E7}.Debug|Win32.Build.0 = Debug|Win32 + {9A22718A-2B37-9BB2-3064-E04B5B92D1E7}.Debug|x64.ActiveCfg = Debug|Win32 + {9A22718A-2B37-9BB2-3064-E04B5B92D1E7}.Release|Win32.ActiveCfg = Release|Win32 + {9A22718A-2B37-9BB2-3064-E04B5B92D1E7}.Release|Win32.Build.0 = Release|Win32 + {9A22718A-2B37-9BB2-3064-E04B5B92D1E7}.Release|x64.ActiveCfg = Release|Win32 + {9A22718A-2B37-9BB2-3064-E04B5B92D1E7}.Template|Win32.ActiveCfg = Template|Win32 + {9A22718A-2B37-9BB2-3064-E04B5B92D1E7}.Template|Win32.Build.0 = Template|Win32 + {9A22718A-2B37-9BB2-3064-E04B5B92D1E7}.Template|x64.ActiveCfg = Template|Win32 + {46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}.Debug|Win32.ActiveCfg = Debug|Win32 + {46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}.Debug|Win32.Build.0 = Debug|Win32 + {46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}.Debug|x64.ActiveCfg = Debug|Win32 + {46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}.Release|Win32.ActiveCfg = Release|Win32 + {46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}.Release|Win32.Build.0 = Release|Win32 + {46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}.Release|x64.ActiveCfg = Release|Win32 + {46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}.Template|Win32.ActiveCfg = Template|Win32 + {46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}.Template|Win32.Build.0 = Template|Win32 + {46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}.Template|x64.ActiveCfg = Template|Win32 + {A58FEE69-867D-1FF4-62BE-6F58020624D0}.Debug|Win32.ActiveCfg = Debug|Win32 + {A58FEE69-867D-1FF4-62BE-6F58020624D0}.Debug|Win32.Build.0 = Debug|Win32 + {A58FEE69-867D-1FF4-62BE-6F58020624D0}.Debug|x64.ActiveCfg = Debug|Win32 + {A58FEE69-867D-1FF4-62BE-6F58020624D0}.Release|Win32.ActiveCfg = Release|Win32 + {A58FEE69-867D-1FF4-62BE-6F58020624D0}.Release|Win32.Build.0 = Release|Win32 + {A58FEE69-867D-1FF4-62BE-6F58020624D0}.Release|x64.ActiveCfg = Release|Win32 + {A58FEE69-867D-1FF4-62BE-6F58020624D0}.Template|Win32.ActiveCfg = Template|Win32 + {A58FEE69-867D-1FF4-62BE-6F58020624D0}.Template|Win32.Build.0 = Template|Win32 + {A58FEE69-867D-1FF4-62BE-6F58020624D0}.Template|x64.ActiveCfg = Template|Win32 + {EC41EC41-BEC3-B108-A96C-304F123869D3}.Debug|Win32.ActiveCfg = Debug|Win32 + {EC41EC41-BEC3-B108-A96C-304F123869D3}.Debug|Win32.Build.0 = Debug|Win32 + {EC41EC41-BEC3-B108-A96C-304F123869D3}.Debug|x64.ActiveCfg = Debug|Win32 + {EC41EC41-BEC3-B108-A96C-304F123869D3}.Release|Win32.ActiveCfg = Release|Win32 + {EC41EC41-BEC3-B108-A96C-304F123869D3}.Release|Win32.Build.0 = Release|Win32 + {EC41EC41-BEC3-B108-A96C-304F123869D3}.Release|x64.ActiveCfg = Release|Win32 + {EC41EC41-BEC3-B108-A96C-304F123869D3}.Template|Win32.ActiveCfg = Template|Win32 + {EC41EC41-BEC3-B108-A96C-304F123869D3}.Template|Win32.Build.0 = Template|Win32 + {EC41EC41-BEC3-B108-A96C-304F123869D3}.Template|x64.ActiveCfg = Template|Win32 + {FBFDF907-772D-20C1-B966-7AA299DEE301}.Debug|Win32.ActiveCfg = Debug|Win32 + {FBFDF907-772D-20C1-B966-7AA299DEE301}.Debug|Win32.Build.0 = Debug|Win32 + {FBFDF907-772D-20C1-B966-7AA299DEE301}.Debug|x64.ActiveCfg = Debug|Win32 + {FBFDF907-772D-20C1-B966-7AA299DEE301}.Release|Win32.ActiveCfg = Release|Win32 + {FBFDF907-772D-20C1-B966-7AA299DEE301}.Release|Win32.Build.0 = Release|Win32 + {FBFDF907-772D-20C1-B966-7AA299DEE301}.Release|x64.ActiveCfg = Release|Win32 + {FBFDF907-772D-20C1-B966-7AA299DEE301}.Template|Win32.ActiveCfg = Template|Win32 + {FBFDF907-772D-20C1-B966-7AA299DEE301}.Template|Win32.Build.0 = Template|Win32 + {FBFDF907-772D-20C1-B966-7AA299DEE301}.Template|x64.ActiveCfg = Template|Win32 + {67D784F4-AE57-86EF-85CB-9EC6CADFF616}.Debug|Win32.ActiveCfg = Debug|Win32 + {67D784F4-AE57-86EF-85CB-9EC6CADFF616}.Debug|Win32.Build.0 = Debug|Win32 + {67D784F4-AE57-86EF-85CB-9EC6CADFF616}.Debug|x64.ActiveCfg = Debug|Win32 + {67D784F4-AE57-86EF-85CB-9EC6CADFF616}.Release|Win32.ActiveCfg = Release|Win32 + {67D784F4-AE57-86EF-85CB-9EC6CADFF616}.Release|Win32.Build.0 = Release|Win32 + {67D784F4-AE57-86EF-85CB-9EC6CADFF616}.Release|x64.ActiveCfg = Release|Win32 + {67D784F4-AE57-86EF-85CB-9EC6CADFF616}.Template|Win32.ActiveCfg = Template|Win32 + {67D784F4-AE57-86EF-85CB-9EC6CADFF616}.Template|Win32.Build.0 = Template|Win32 + {67D784F4-AE57-86EF-85CB-9EC6CADFF616}.Template|x64.ActiveCfg = Template|Win32 + {7CB77339-97A9-1507-BF82-11BD57A3733B}.Debug|Win32.ActiveCfg = Debug|Win32 + {7CB77339-97A9-1507-BF82-11BD57A3733B}.Debug|Win32.Build.0 = Debug|Win32 + {7CB77339-97A9-1507-BF82-11BD57A3733B}.Debug|x64.ActiveCfg = Debug|Win32 + {7CB77339-97A9-1507-BF82-11BD57A3733B}.Release|Win32.ActiveCfg = Release|Win32 + {7CB77339-97A9-1507-BF82-11BD57A3733B}.Release|Win32.Build.0 = Release|Win32 + {7CB77339-97A9-1507-BF82-11BD57A3733B}.Release|x64.ActiveCfg = Release|Win32 + {7CB77339-97A9-1507-BF82-11BD57A3733B}.Template|Win32.ActiveCfg = Template|Win32 + {7CB77339-97A9-1507-BF82-11BD57A3733B}.Template|Win32.Build.0 = Template|Win32 + {7CB77339-97A9-1507-BF82-11BD57A3733B}.Template|x64.ActiveCfg = Template|Win32 + {CCCB62D2-F473-1858-6280-12EB5371C317}.Debug|Win32.ActiveCfg = Debug|Win32 + {CCCB62D2-F473-1858-6280-12EB5371C317}.Debug|Win32.Build.0 = Debug|Win32 + {CCCB62D2-F473-1858-6280-12EB5371C317}.Debug|x64.ActiveCfg = Debug|Win32 + {CCCB62D2-F473-1858-6280-12EB5371C317}.Release|Win32.ActiveCfg = Release|Win32 + {CCCB62D2-F473-1858-6280-12EB5371C317}.Release|Win32.Build.0 = Release|Win32 + {CCCB62D2-F473-1858-6280-12EB5371C317}.Release|x64.ActiveCfg = Release|Win32 + {CCCB62D2-F473-1858-6280-12EB5371C317}.Template|Win32.ActiveCfg = Template|Win32 + {CCCB62D2-F473-1858-6280-12EB5371C317}.Template|Win32.Build.0 = Template|Win32 + {CCCB62D2-F473-1858-6280-12EB5371C317}.Template|x64.ActiveCfg = Template|Win32 + {FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}.Debug|Win32.ActiveCfg = Debug|Win32 + {FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}.Debug|Win32.Build.0 = Debug|Win32 + {FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}.Debug|x64.ActiveCfg = Debug|Win32 + {FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}.Release|Win32.ActiveCfg = Release|Win32 + {FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}.Release|Win32.Build.0 = Release|Win32 + {FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}.Release|x64.ActiveCfg = Release|Win32 + {FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}.Template|Win32.ActiveCfg = Template|Win32 + {FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}.Template|Win32.Build.0 = Template|Win32 + {FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}.Template|x64.ActiveCfg = Template|Win32 + {AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}.Debug|Win32.ActiveCfg = Debug|Win32 + {AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}.Debug|Win32.Build.0 = Debug|Win32 + {AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}.Debug|x64.ActiveCfg = Debug|Win32 + {AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}.Release|Win32.ActiveCfg = Release|Win32 + {AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}.Release|Win32.Build.0 = Release|Win32 + {AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}.Release|x64.ActiveCfg = Release|Win32 + {AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}.Template|Win32.ActiveCfg = Template|Win32 + {AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}.Template|Win32.Build.0 = Template|Win32 + {AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}.Template|x64.ActiveCfg = Template|Win32 + {1AC06016-EA58-2079-0D9E-E85B198188B6}.Debug|Win32.ActiveCfg = Debug|Win32 + {1AC06016-EA58-2079-0D9E-E85B198188B6}.Debug|Win32.Build.0 = Debug|Win32 + {1AC06016-EA58-2079-0D9E-E85B198188B6}.Debug|x64.ActiveCfg = Debug|Win32 + {1AC06016-EA58-2079-0D9E-E85B198188B6}.Release|Win32.ActiveCfg = Release|Win32 + {1AC06016-EA58-2079-0D9E-E85B198188B6}.Release|Win32.Build.0 = Release|Win32 + {1AC06016-EA58-2079-0D9E-E85B198188B6}.Release|x64.ActiveCfg = Release|Win32 + {1AC06016-EA58-2079-0D9E-E85B198188B6}.Template|Win32.ActiveCfg = Template|Win32 + {1AC06016-EA58-2079-0D9E-E85B198188B6}.Template|Win32.Build.0 = Template|Win32 + {1AC06016-EA58-2079-0D9E-E85B198188B6}.Template|x64.ActiveCfg = Template|Win32 + {B7F52AEF-C4E7-049C-3C28-902A52C24D9D}.Debug|Win32.ActiveCfg = Debug|Win32 + {B7F52AEF-C4E7-049C-3C28-902A52C24D9D}.Debug|Win32.Build.0 = Debug|Win32 + {B7F52AEF-C4E7-049C-3C28-902A52C24D9D}.Debug|x64.ActiveCfg = Debug|Win32 + {B7F52AEF-C4E7-049C-3C28-902A52C24D9D}.Release|Win32.ActiveCfg = Release|Win32 + {B7F52AEF-C4E7-049C-3C28-902A52C24D9D}.Release|Win32.Build.0 = Release|Win32 + {B7F52AEF-C4E7-049C-3C28-902A52C24D9D}.Release|x64.ActiveCfg = Release|Win32 + {B7F52AEF-C4E7-049C-3C28-902A52C24D9D}.Template|Win32.ActiveCfg = Template|Win32 + {B7F52AEF-C4E7-049C-3C28-902A52C24D9D}.Template|Win32.Build.0 = Template|Win32 + {B7F52AEF-C4E7-049C-3C28-902A52C24D9D}.Template|x64.ActiveCfg = Template|Win32 + {636E09D4-0678-A349-3C54-B4F5D29D2440}.Debug|Win32.ActiveCfg = Debug|Win32 + {636E09D4-0678-A349-3C54-B4F5D29D2440}.Debug|Win32.Build.0 = Debug|Win32 + {636E09D4-0678-A349-3C54-B4F5D29D2440}.Debug|x64.ActiveCfg = Debug|Win32 + {636E09D4-0678-A349-3C54-B4F5D29D2440}.Release|Win32.ActiveCfg = Release|Win32 + {636E09D4-0678-A349-3C54-B4F5D29D2440}.Release|Win32.Build.0 = Release|Win32 + {636E09D4-0678-A349-3C54-B4F5D29D2440}.Release|x64.ActiveCfg = Release|Win32 + {636E09D4-0678-A349-3C54-B4F5D29D2440}.Template|Win32.ActiveCfg = Template|Win32 + {636E09D4-0678-A349-3C54-B4F5D29D2440}.Template|Win32.Build.0 = Template|Win32 + {636E09D4-0678-A349-3C54-B4F5D29D2440}.Template|x64.ActiveCfg = Template|Win32 + {F61620DA-B261-3836-F808-29991B8EB622}.Debug|Win32.ActiveCfg = Debug|Win32 + {F61620DA-B261-3836-F808-29991B8EB622}.Debug|Win32.Build.0 = Debug|Win32 + {F61620DA-B261-3836-F808-29991B8EB622}.Debug|x64.ActiveCfg = Debug|Win32 + {F61620DA-B261-3836-F808-29991B8EB622}.Release|Win32.ActiveCfg = Release|Win32 + {F61620DA-B261-3836-F808-29991B8EB622}.Release|Win32.Build.0 = Release|Win32 + {F61620DA-B261-3836-F808-29991B8EB622}.Release|x64.ActiveCfg = Release|Win32 + {F61620DA-B261-3836-F808-29991B8EB622}.Template|Win32.ActiveCfg = Template|Win32 + {F61620DA-B261-3836-F808-29991B8EB622}.Template|Win32.Build.0 = Template|Win32 + {F61620DA-B261-3836-F808-29991B8EB622}.Template|x64.ActiveCfg = Template|Win32 + {1C282CA7-6080-A229-B4BD-22BFC1E56A0D}.Debug|Win32.ActiveCfg = Debug|Win32 + {1C282CA7-6080-A229-B4BD-22BFC1E56A0D}.Debug|Win32.Build.0 = Debug|Win32 + {1C282CA7-6080-A229-B4BD-22BFC1E56A0D}.Debug|x64.ActiveCfg = Debug|Win32 + {1C282CA7-6080-A229-B4BD-22BFC1E56A0D}.Release|Win32.ActiveCfg = Release|Win32 + {1C282CA7-6080-A229-B4BD-22BFC1E56A0D}.Release|Win32.Build.0 = Release|Win32 + {1C282CA7-6080-A229-B4BD-22BFC1E56A0D}.Release|x64.ActiveCfg = Release|Win32 + {1C282CA7-6080-A229-B4BD-22BFC1E56A0D}.Template|Win32.ActiveCfg = Template|Win32 + {1C282CA7-6080-A229-B4BD-22BFC1E56A0D}.Template|Win32.Build.0 = Template|Win32 + {1C282CA7-6080-A229-B4BD-22BFC1E56A0D}.Template|x64.ActiveCfg = Template|Win32 + {DA6B065B-8BD3-ADCD-28D7-D4BB41003200}.Debug|Win32.ActiveCfg = Debug|Win32 + {DA6B065B-8BD3-ADCD-28D7-D4BB41003200}.Debug|Win32.Build.0 = Debug|Win32 + {DA6B065B-8BD3-ADCD-28D7-D4BB41003200}.Debug|x64.ActiveCfg = Debug|Win32 + {DA6B065B-8BD3-ADCD-28D7-D4BB41003200}.Release|Win32.ActiveCfg = Release|Win32 + {DA6B065B-8BD3-ADCD-28D7-D4BB41003200}.Release|Win32.Build.0 = Release|Win32 + {DA6B065B-8BD3-ADCD-28D7-D4BB41003200}.Release|x64.ActiveCfg = Release|Win32 + {DA6B065B-8BD3-ADCD-28D7-D4BB41003200}.Template|Win32.ActiveCfg = Template|Win32 + {DA6B065B-8BD3-ADCD-28D7-D4BB41003200}.Template|Win32.Build.0 = Template|Win32 + {DA6B065B-8BD3-ADCD-28D7-D4BB41003200}.Template|x64.ActiveCfg = Template|Win32 + {7784A618-B98E-55A1-EB91-92B1BACE7C30}.Debug|Win32.ActiveCfg = Debug|Win32 + {7784A618-B98E-55A1-EB91-92B1BACE7C30}.Debug|Win32.Build.0 = Debug|Win32 + {7784A618-B98E-55A1-EB91-92B1BACE7C30}.Debug|x64.ActiveCfg = Debug|Win32 + {7784A618-B98E-55A1-EB91-92B1BACE7C30}.Release|Win32.ActiveCfg = Release|Win32 + {7784A618-B98E-55A1-EB91-92B1BACE7C30}.Release|Win32.Build.0 = Release|Win32 + {7784A618-B98E-55A1-EB91-92B1BACE7C30}.Release|x64.ActiveCfg = Release|Win32 + {7784A618-B98E-55A1-EB91-92B1BACE7C30}.Template|Win32.ActiveCfg = Template|Win32 + {7784A618-B98E-55A1-EB91-92B1BACE7C30}.Template|Win32.Build.0 = Template|Win32 + {7784A618-B98E-55A1-EB91-92B1BACE7C30}.Template|x64.ActiveCfg = Template|Win32 + {4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}.Debug|Win32.ActiveCfg = Debug|Win32 + {4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}.Debug|Win32.Build.0 = Debug|Win32 + {4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}.Debug|x64.ActiveCfg = Debug|Win32 + {4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}.Release|Win32.ActiveCfg = Release|Win32 + {4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}.Release|Win32.Build.0 = Release|Win32 + {4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}.Release|x64.ActiveCfg = Release|Win32 + {4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}.Template|Win32.ActiveCfg = Template|Win32 + {4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}.Template|Win32.Build.0 = Template|Win32 + {4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}.Template|x64.ActiveCfg = Template|Win32 + {48F212BB-AAEA-A634-2A87-90A48D73486E}.Debug|Win32.ActiveCfg = Debug|Win32 + {48F212BB-AAEA-A634-2A87-90A48D73486E}.Debug|Win32.Build.0 = Debug|Win32 + {48F212BB-AAEA-A634-2A87-90A48D73486E}.Debug|x64.ActiveCfg = Debug|Win32 + {48F212BB-AAEA-A634-2A87-90A48D73486E}.Release|Win32.ActiveCfg = Release|Win32 + {48F212BB-AAEA-A634-2A87-90A48D73486E}.Release|Win32.Build.0 = Release|Win32 + {48F212BB-AAEA-A634-2A87-90A48D73486E}.Release|x64.ActiveCfg = Release|Win32 + {48F212BB-AAEA-A634-2A87-90A48D73486E}.Template|Win32.ActiveCfg = Template|Win32 + {48F212BB-AAEA-A634-2A87-90A48D73486E}.Template|Win32.Build.0 = Template|Win32 + {48F212BB-AAEA-A634-2A87-90A48D73486E}.Template|x64.ActiveCfg = Template|Win32 + {9E72EC9B-93D8-D749-88D7-25742B73A303}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E72EC9B-93D8-D749-88D7-25742B73A303}.Debug|Win32.Build.0 = Debug|Win32 + {9E72EC9B-93D8-D749-88D7-25742B73A303}.Debug|x64.ActiveCfg = Debug|Win32 + {9E72EC9B-93D8-D749-88D7-25742B73A303}.Release|Win32.ActiveCfg = Release|Win32 + {9E72EC9B-93D8-D749-88D7-25742B73A303}.Release|Win32.Build.0 = Release|Win32 + {9E72EC9B-93D8-D749-88D7-25742B73A303}.Release|x64.ActiveCfg = Release|Win32 + {9E72EC9B-93D8-D749-88D7-25742B73A303}.Template|Win32.ActiveCfg = Template|Win32 + {9E72EC9B-93D8-D749-88D7-25742B73A303}.Template|Win32.Build.0 = Template|Win32 + {9E72EC9B-93D8-D749-88D7-25742B73A303}.Template|x64.ActiveCfg = Template|Win32 + {01580078-9E68-4ECA-9C68-334F1CF215C2}.Debug|Win32.ActiveCfg = Debug|Win32 + {01580078-9E68-4ECA-9C68-334F1CF215C2}.Debug|Win32.Build.0 = Debug|Win32 + {01580078-9E68-4ECA-9C68-334F1CF215C2}.Debug|x64.ActiveCfg = Debug|Win32 + {01580078-9E68-4ECA-9C68-334F1CF215C2}.Release|Win32.ActiveCfg = Release|Win32 + {01580078-9E68-4ECA-9C68-334F1CF215C2}.Release|Win32.Build.0 = Release|Win32 + {01580078-9E68-4ECA-9C68-334F1CF215C2}.Release|x64.ActiveCfg = Release|Win32 + {01580078-9E68-4ECA-9C68-334F1CF215C2}.Template|Win32.ActiveCfg = Template|Win32 + {01580078-9E68-4ECA-9C68-334F1CF215C2}.Template|Win32.Build.0 = Template|Win32 + {01580078-9E68-4ECA-9C68-334F1CF215C2}.Template|x64.ActiveCfg = Template|Win32 + {B1879B0F-4ACA-B943-3474-E584D659362F}.Debug|Win32.ActiveCfg = Debug|Win32 + {B1879B0F-4ACA-B943-3474-E584D659362F}.Debug|Win32.Build.0 = Debug|Win32 + {B1879B0F-4ACA-B943-3474-E584D659362F}.Debug|x64.ActiveCfg = Debug|Win32 + {B1879B0F-4ACA-B943-3474-E584D659362F}.Release|Win32.ActiveCfg = Release|Win32 + {B1879B0F-4ACA-B943-3474-E584D659362F}.Release|Win32.Build.0 = Release|Win32 + {B1879B0F-4ACA-B943-3474-E584D659362F}.Release|x64.ActiveCfg = Release|Win32 + {B1879B0F-4ACA-B943-3474-E584D659362F}.Template|Win32.ActiveCfg = Template|Win32 + {B1879B0F-4ACA-B943-3474-E584D659362F}.Template|Win32.Build.0 = Template|Win32 + {B1879B0F-4ACA-B943-3474-E584D659362F}.Template|x64.ActiveCfg = Template|Win32 + {EBCB363B-3793-507F-559E-30FF760ACB03}.Debug|Win32.ActiveCfg = Debug|Win32 + {EBCB363B-3793-507F-559E-30FF760ACB03}.Debug|Win32.Build.0 = Debug|Win32 + {EBCB363B-3793-507F-559E-30FF760ACB03}.Debug|x64.ActiveCfg = Debug|Win32 + {EBCB363B-3793-507F-559E-30FF760ACB03}.Release|Win32.ActiveCfg = Release|Win32 + {EBCB363B-3793-507F-559E-30FF760ACB03}.Release|Win32.Build.0 = Release|Win32 + {EBCB363B-3793-507F-559E-30FF760ACB03}.Release|x64.ActiveCfg = Release|Win32 + {EBCB363B-3793-507F-559E-30FF760ACB03}.Template|Win32.ActiveCfg = Template|Win32 + {EBCB363B-3793-507F-559E-30FF760ACB03}.Template|Win32.Build.0 = Template|Win32 + {EBCB363B-3793-507F-559E-30FF760ACB03}.Template|x64.ActiveCfg = Template|Win32 + {CEA11124-03C2-06D5-39DC-9E9866B05B99}.Debug|Win32.ActiveCfg = Debug|Win32 + {CEA11124-03C2-06D5-39DC-9E9866B05B99}.Debug|Win32.Build.0 = Debug|Win32 + {CEA11124-03C2-06D5-39DC-9E9866B05B99}.Debug|x64.ActiveCfg = Debug|Win32 + {CEA11124-03C2-06D5-39DC-9E9866B05B99}.Release|Win32.ActiveCfg = Release|Win32 + {CEA11124-03C2-06D5-39DC-9E9866B05B99}.Release|Win32.Build.0 = Release|Win32 + {CEA11124-03C2-06D5-39DC-9E9866B05B99}.Release|x64.ActiveCfg = Release|Win32 + {CEA11124-03C2-06D5-39DC-9E9866B05B99}.Template|Win32.ActiveCfg = Template|Win32 + {CEA11124-03C2-06D5-39DC-9E9866B05B99}.Template|Win32.Build.0 = Template|Win32 + {CEA11124-03C2-06D5-39DC-9E9866B05B99}.Template|x64.ActiveCfg = Template|Win32 + {D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}.Debug|Win32.ActiveCfg = Debug|Win32 + {D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}.Debug|Win32.Build.0 = Debug|Win32 + {D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}.Debug|x64.ActiveCfg = Debug|Win32 + {D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}.Release|Win32.ActiveCfg = Release|Win32 + {D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}.Release|Win32.Build.0 = Release|Win32 + {D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}.Release|x64.ActiveCfg = Release|Win32 + {D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}.Template|Win32.ActiveCfg = Template|Win32 + {D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}.Template|Win32.Build.0 = Template|Win32 + {D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}.Template|x64.ActiveCfg = Template|Win32 + {62F9D117-6886-87C3-B719-D59791638994}.Debug|Win32.ActiveCfg = Debug|Win32 + {62F9D117-6886-87C3-B719-D59791638994}.Debug|Win32.Build.0 = Debug|Win32 + {62F9D117-6886-87C3-B719-D59791638994}.Debug|x64.ActiveCfg = Debug|Win32 + {62F9D117-6886-87C3-B719-D59791638994}.Release|Win32.ActiveCfg = Release|Win32 + {62F9D117-6886-87C3-B719-D59791638994}.Release|Win32.Build.0 = Release|Win32 + {62F9D117-6886-87C3-B719-D59791638994}.Release|x64.ActiveCfg = Release|Win32 + {62F9D117-6886-87C3-B719-D59791638994}.Template|Win32.ActiveCfg = Template|Win32 + {62F9D117-6886-87C3-B719-D59791638994}.Template|Win32.Build.0 = Template|Win32 + {62F9D117-6886-87C3-B719-D59791638994}.Template|x64.ActiveCfg = Template|Win32 + {3DDFB788-8751-3001-00EF-B3E42C09FFD1}.Debug|Win32.ActiveCfg = Debug|Win32 + {3DDFB788-8751-3001-00EF-B3E42C09FFD1}.Debug|Win32.Build.0 = Debug|Win32 + {3DDFB788-8751-3001-00EF-B3E42C09FFD1}.Debug|x64.ActiveCfg = Debug|Win32 + {3DDFB788-8751-3001-00EF-B3E42C09FFD1}.Release|Win32.ActiveCfg = Release|Win32 + {3DDFB788-8751-3001-00EF-B3E42C09FFD1}.Release|Win32.Build.0 = Release|Win32 + {3DDFB788-8751-3001-00EF-B3E42C09FFD1}.Release|x64.ActiveCfg = Release|Win32 + {3DDFB788-8751-3001-00EF-B3E42C09FFD1}.Template|Win32.ActiveCfg = Template|Win32 + {3DDFB788-8751-3001-00EF-B3E42C09FFD1}.Template|Win32.Build.0 = Template|Win32 + {3DDFB788-8751-3001-00EF-B3E42C09FFD1}.Template|x64.ActiveCfg = Template|Win32 + {FAA982B0-05C2-6440-9EC2-C0032CE56B4F}.Debug|Win32.ActiveCfg = Debug|Win32 + {FAA982B0-05C2-6440-9EC2-C0032CE56B4F}.Debug|Win32.Build.0 = Debug|Win32 + {FAA982B0-05C2-6440-9EC2-C0032CE56B4F}.Debug|x64.ActiveCfg = Debug|Win32 + {FAA982B0-05C2-6440-9EC2-C0032CE56B4F}.Release|Win32.ActiveCfg = Release|Win32 + {FAA982B0-05C2-6440-9EC2-C0032CE56B4F}.Release|Win32.Build.0 = Release|Win32 + {FAA982B0-05C2-6440-9EC2-C0032CE56B4F}.Release|x64.ActiveCfg = Release|Win32 + {FAA982B0-05C2-6440-9EC2-C0032CE56B4F}.Template|Win32.ActiveCfg = Template|Win32 + {FAA982B0-05C2-6440-9EC2-C0032CE56B4F}.Template|Win32.Build.0 = Template|Win32 + {FAA982B0-05C2-6440-9EC2-C0032CE56B4F}.Template|x64.ActiveCfg = Template|Win32 + {88AC3D30-0084-D856-77C4-AB749ED4FFAA}.Debug|Win32.ActiveCfg = Debug|Win32 + {88AC3D30-0084-D856-77C4-AB749ED4FFAA}.Debug|Win32.Build.0 = Debug|Win32 + {88AC3D30-0084-D856-77C4-AB749ED4FFAA}.Debug|x64.ActiveCfg = Debug|Win32 + {88AC3D30-0084-D856-77C4-AB749ED4FFAA}.Release|Win32.ActiveCfg = Release|Win32 + {88AC3D30-0084-D856-77C4-AB749ED4FFAA}.Release|Win32.Build.0 = Release|Win32 + {88AC3D30-0084-D856-77C4-AB749ED4FFAA}.Release|x64.ActiveCfg = Release|Win32 + {88AC3D30-0084-D856-77C4-AB749ED4FFAA}.Template|Win32.ActiveCfg = Template|Win32 + {88AC3D30-0084-D856-77C4-AB749ED4FFAA}.Template|Win32.Build.0 = Template|Win32 + {88AC3D30-0084-D856-77C4-AB749ED4FFAA}.Template|x64.ActiveCfg = Template|Win32 + {F2CDDE95-2042-51DD-50AF-8CB33C91A363}.Debug|Win32.ActiveCfg = Debug|Win32 + {F2CDDE95-2042-51DD-50AF-8CB33C91A363}.Debug|Win32.Build.0 = Debug|Win32 + {F2CDDE95-2042-51DD-50AF-8CB33C91A363}.Debug|x64.ActiveCfg = Debug|Win32 + {F2CDDE95-2042-51DD-50AF-8CB33C91A363}.Release|Win32.ActiveCfg = Release|Win32 + {F2CDDE95-2042-51DD-50AF-8CB33C91A363}.Release|Win32.Build.0 = Release|Win32 + {F2CDDE95-2042-51DD-50AF-8CB33C91A363}.Release|x64.ActiveCfg = Release|Win32 + {F2CDDE95-2042-51DD-50AF-8CB33C91A363}.Template|Win32.ActiveCfg = Template|Win32 + {F2CDDE95-2042-51DD-50AF-8CB33C91A363}.Template|Win32.Build.0 = Template|Win32 + {F2CDDE95-2042-51DD-50AF-8CB33C91A363}.Template|x64.ActiveCfg = Template|Win32 + {04837E0B-4CCF-A526-E9EC-E78EA4640AEB}.Debug|Win32.ActiveCfg = Debug|Win32 + {04837E0B-4CCF-A526-E9EC-E78EA4640AEB}.Debug|Win32.Build.0 = Debug|Win32 + {04837E0B-4CCF-A526-E9EC-E78EA4640AEB}.Debug|x64.ActiveCfg = Debug|Win32 + {04837E0B-4CCF-A526-E9EC-E78EA4640AEB}.Release|Win32.ActiveCfg = Release|Win32 + {04837E0B-4CCF-A526-E9EC-E78EA4640AEB}.Release|Win32.Build.0 = Release|Win32 + {04837E0B-4CCF-A526-E9EC-E78EA4640AEB}.Release|x64.ActiveCfg = Release|Win32 + {04837E0B-4CCF-A526-E9EC-E78EA4640AEB}.Template|Win32.ActiveCfg = Template|Win32 + {04837E0B-4CCF-A526-E9EC-E78EA4640AEB}.Template|Win32.Build.0 = Template|Win32 + {04837E0B-4CCF-A526-E9EC-E78EA4640AEB}.Template|x64.ActiveCfg = Template|Win32 + {ABE48445-AD58-FBBA-6693-E5B8701BC6CF}.Debug|Win32.ActiveCfg = Debug|Win32 + {ABE48445-AD58-FBBA-6693-E5B8701BC6CF}.Debug|Win32.Build.0 = Debug|Win32 + {ABE48445-AD58-FBBA-6693-E5B8701BC6CF}.Debug|x64.ActiveCfg = Debug|Win32 + {ABE48445-AD58-FBBA-6693-E5B8701BC6CF}.Release|Win32.ActiveCfg = Release|Win32 + {ABE48445-AD58-FBBA-6693-E5B8701BC6CF}.Release|Win32.Build.0 = Release|Win32 + {ABE48445-AD58-FBBA-6693-E5B8701BC6CF}.Release|x64.ActiveCfg = Release|Win32 + {ABE48445-AD58-FBBA-6693-E5B8701BC6CF}.Template|Win32.ActiveCfg = Template|Win32 + {ABE48445-AD58-FBBA-6693-E5B8701BC6CF}.Template|Win32.Build.0 = Template|Win32 + {ABE48445-AD58-FBBA-6693-E5B8701BC6CF}.Template|x64.ActiveCfg = Template|Win32 + {BF39ECC1-095F-E7FB-BBB6-563332B4470F}.Debug|Win32.ActiveCfg = Debug|Win32 + {BF39ECC1-095F-E7FB-BBB6-563332B4470F}.Debug|Win32.Build.0 = Debug|Win32 + {BF39ECC1-095F-E7FB-BBB6-563332B4470F}.Debug|x64.ActiveCfg = Debug|Win32 + {BF39ECC1-095F-E7FB-BBB6-563332B4470F}.Release|Win32.ActiveCfg = Release|Win32 + {BF39ECC1-095F-E7FB-BBB6-563332B4470F}.Release|Win32.Build.0 = Release|Win32 + {BF39ECC1-095F-E7FB-BBB6-563332B4470F}.Release|x64.ActiveCfg = Release|Win32 + {BF39ECC1-095F-E7FB-BBB6-563332B4470F}.Template|Win32.ActiveCfg = Template|Win32 + {BF39ECC1-095F-E7FB-BBB6-563332B4470F}.Template|Win32.Build.0 = Template|Win32 + {BF39ECC1-095F-E7FB-BBB6-563332B4470F}.Template|x64.ActiveCfg = Template|Win32 + {EA706565-3FDB-5B31-6C36-C27C2AD257EF}.Debug|Win32.ActiveCfg = Debug|Win32 + {EA706565-3FDB-5B31-6C36-C27C2AD257EF}.Debug|Win32.Build.0 = Debug|Win32 + {EA706565-3FDB-5B31-6C36-C27C2AD257EF}.Debug|x64.ActiveCfg = Debug|Win32 + {EA706565-3FDB-5B31-6C36-C27C2AD257EF}.Release|Win32.ActiveCfg = Release|Win32 + {EA706565-3FDB-5B31-6C36-C27C2AD257EF}.Release|Win32.Build.0 = Release|Win32 + {EA706565-3FDB-5B31-6C36-C27C2AD257EF}.Release|x64.ActiveCfg = Release|Win32 + {EA706565-3FDB-5B31-6C36-C27C2AD257EF}.Template|Win32.ActiveCfg = Template|Win32 + {EA706565-3FDB-5B31-6C36-C27C2AD257EF}.Template|Win32.Build.0 = Template|Win32 + {EA706565-3FDB-5B31-6C36-C27C2AD257EF}.Template|x64.ActiveCfg = Template|Win32 + {6015656F-2EE0-42FD-9EE3-DE54A429EE00}.Debug|Win32.ActiveCfg = Debug|Win32 + {6015656F-2EE0-42FD-9EE3-DE54A429EE00}.Debug|Win32.Build.0 = Debug|Win32 + {6015656F-2EE0-42FD-9EE3-DE54A429EE00}.Debug|x64.ActiveCfg = Debug|Win32 + {6015656F-2EE0-42FD-9EE3-DE54A429EE00}.Release|Win32.ActiveCfg = Release|Win32 + {6015656F-2EE0-42FD-9EE3-DE54A429EE00}.Release|Win32.Build.0 = Release|Win32 + {6015656F-2EE0-42FD-9EE3-DE54A429EE00}.Release|x64.ActiveCfg = Release|Win32 + {6015656F-2EE0-42FD-9EE3-DE54A429EE00}.Template|Win32.ActiveCfg = Release|Win32 + {6015656F-2EE0-42FD-9EE3-DE54A429EE00}.Template|Win32.Build.0 = Release|Win32 + {6015656F-2EE0-42FD-9EE3-DE54A429EE00}.Template|x64.ActiveCfg = Release|Win32 + {5E787227-E9A9-4839-AD18-6CDC16C6D1A6}.Debug|Win32.ActiveCfg = Debug|Win32 + {5E787227-E9A9-4839-AD18-6CDC16C6D1A6}.Debug|Win32.Build.0 = Debug|Win32 + {5E787227-E9A9-4839-AD18-6CDC16C6D1A6}.Debug|x64.ActiveCfg = Debug|Win32 + {5E787227-E9A9-4839-AD18-6CDC16C6D1A6}.Release|Win32.ActiveCfg = Release|Win32 + {5E787227-E9A9-4839-AD18-6CDC16C6D1A6}.Release|Win32.Build.0 = Release|Win32 + {5E787227-E9A9-4839-AD18-6CDC16C6D1A6}.Release|x64.ActiveCfg = Release|Win32 + {5E787227-E9A9-4839-AD18-6CDC16C6D1A6}.Template|Win32.ActiveCfg = Release|Win32 + {5E787227-E9A9-4839-AD18-6CDC16C6D1A6}.Template|Win32.Build.0 = Release|Win32 + {5E787227-E9A9-4839-AD18-6CDC16C6D1A6}.Template|x64.ActiveCfg = Release|Win32 + {6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}.Debug|Win32.ActiveCfg = Debug|Win32 + {6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}.Debug|Win32.Build.0 = Debug|Win32 + {6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}.Debug|x64.ActiveCfg = Debug|Win32 + {6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}.Release|Win32.ActiveCfg = Release|Win32 + {6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}.Release|Win32.Build.0 = Release|Win32 + {6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}.Release|x64.ActiveCfg = Release|Win32 + {6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}.Template|Win32.ActiveCfg = Template|Win32 + {6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}.Template|Win32.Build.0 = Template|Win32 + {6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}.Template|x64.ActiveCfg = Template|Win32 + {A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}.Debug|Win32.ActiveCfg = Debug|Win32 + {A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}.Debug|Win32.Build.0 = Debug|Win32 + {A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}.Debug|x64.ActiveCfg = Debug|Win32 + {A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}.Release|Win32.ActiveCfg = Release|Win32 + {A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}.Release|Win32.Build.0 = Release|Win32 + {A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}.Release|x64.ActiveCfg = Release|Win32 + {A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}.Template|Win32.ActiveCfg = Template|Win32 + {A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}.Template|Win32.Build.0 = Template|Win32 + {A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}.Template|x64.ActiveCfg = Template|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/examples/win32_api/flash_rasterizer/Makefile b/examples/win32_api/flash_rasterizer/Makefile new file mode 100644 index 0000000..3e5cd8a --- /dev/null +++ b/examples/win32_api/flash_rasterizer/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=flash_rasterizer +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/flash_rasterizer/flash_rasterizer.dsp b/examples/win32_api/flash_rasterizer/flash_rasterizer.dsp new file mode 100644 index 0000000..1c1593f --- /dev/null +++ b/examples/win32_api/flash_rasterizer/flash_rasterizer.dsp @@ -0,0 +1,147 @@ +# Microsoft Developer Studio Project File - Name="flash_rasterizer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=flash_rasterizer - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "flash_rasterizer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "flash_rasterizer.mak" CFG="flash_rasterizer - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "flash_rasterizer - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "flash_rasterizer - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "flash_rasterizer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./flash_rasterizer.exe" + +!ELSEIF "$(CFG)" == "flash_rasterizer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "flash_rasterizer - Win32 Release" +# Name "flash_rasterizer - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_polygon_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\flash_rasterizer.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_color_gray.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/flash_rasterizer/flash_rasterizer.dsw b/examples/win32_api/flash_rasterizer/flash_rasterizer.dsw new file mode 100644 index 0000000..859988f --- /dev/null +++ b/examples/win32_api/flash_rasterizer/flash_rasterizer.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "flash_rasterizer"=.\flash_rasterizer.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/flash_rasterizer/flash_rasterizer.vcxproj b/examples/win32_api/flash_rasterizer/flash_rasterizer.vcxproj new file mode 100644 index 0000000..1efaec7 --- /dev/null +++ b/examples/win32_api/flash_rasterizer/flash_rasterizer.vcxproj @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5B5D6A22-5741-5122-FC5E-5DFBBCD5168F}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\flash_rasterizer.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\flash_rasterizer.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\flash_rasterizer.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\flash_rasterizer.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\flash_rasterizer.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\flash_rasterizer.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\flash_rasterizer.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\flash_rasterizer.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_polygon_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\flash_rasterizer.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_color_gray.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/flash_rasterizer2/Makefile b/examples/win32_api/flash_rasterizer2/Makefile new file mode 100644 index 0000000..b231094 --- /dev/null +++ b/examples/win32_api/flash_rasterizer2/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=flash_rasterizer2 +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/flash_rasterizer2/flash_rasterizer2.dsp b/examples/win32_api/flash_rasterizer2/flash_rasterizer2.dsp new file mode 100644 index 0000000..b56b664 --- /dev/null +++ b/examples/win32_api/flash_rasterizer2/flash_rasterizer2.dsp @@ -0,0 +1,143 @@ +# Microsoft Developer Studio Project File - Name="flash_rasterizer2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=flash_rasterizer2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "flash_rasterizer2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "flash_rasterizer2.mak" CFG="flash_rasterizer2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "flash_rasterizer2 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "flash_rasterizer2 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "flash_rasterizer2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./flash_rasterizer2.exe" + +!ELSEIF "$(CFG)" == "flash_rasterizer2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "flash_rasterizer2 - Win32 Release" +# Name "flash_rasterizer2 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_polygon_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\flash_rasterizer2.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/flash_rasterizer2/flash_rasterizer2.dsw b/examples/win32_api/flash_rasterizer2/flash_rasterizer2.dsw new file mode 100644 index 0000000..8afaae1 --- /dev/null +++ b/examples/win32_api/flash_rasterizer2/flash_rasterizer2.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "flash_rasterizer2"=.\flash_rasterizer2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/flash_rasterizer2/flash_rasterizer2.vcxproj b/examples/win32_api/flash_rasterizer2/flash_rasterizer2.vcxproj new file mode 100644 index 0000000..9dcdc58 --- /dev/null +++ b/examples/win32_api/flash_rasterizer2/flash_rasterizer2.vcxproj @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D873A8A1-683A-B8CA-DAC8-E17948138BAE}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\flash_rasterizer2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\flash_rasterizer2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\flash_rasterizer2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\flash_rasterizer2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\flash_rasterizer2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\flash_rasterizer2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\flash_rasterizer2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\flash_rasterizer2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_polygon_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\flash_rasterizer2.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/freetype_test/Makefile b/examples/win32_api/freetype_test/Makefile new file mode 100644 index 0000000..29414b8 --- /dev/null +++ b/examples/win32_api/freetype_test/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=scanline_boolean2 +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../make_arrows.cpp \ +../../make_gb_poly.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../*.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/freetype_test/freetype_test.dsp b/examples/win32_api/freetype_test/freetype_test.dsp new file mode 100644 index 0000000..82fb2f9 --- /dev/null +++ b/examples/win32_api/freetype_test/freetype_test.dsp @@ -0,0 +1,159 @@ +# Microsoft Developer Studio Project File - Name="freetype_test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=freetype_test - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "freetype_test.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "freetype_test.mak" CFG="freetype_test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "freetype_test - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "freetype_test - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "freetype_test - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /I "../../../font_freetype" /I "../../../../freetype2/include" /I "../../../../freetype2/src" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib freetype219.lib /nologo /subsystem:windows /machine:I386 /out:"./freetype_test.exe" /libpath:"../../../../freetype2/objs" + +!ELSEIF "$(CFG)" == "freetype_test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../font_freetype" /I "../../../../freetype2/include" /I "../../../../freetype2/src" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib freetype219_D.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /libpath:"../../../../freetype2/objs" + +!ENDIF + +# Begin Target + +# Name "freetype_test - Win32 Release" +# Name "freetype_test - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\font_freetype\agg_font_freetype.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\freetype_test.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\font_freetype\agg_font_freetype.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/freetype_test/freetype_test.dsw b/examples/win32_api/freetype_test/freetype_test.dsw new file mode 100644 index 0000000..36b18b8 --- /dev/null +++ b/examples/win32_api/freetype_test/freetype_test.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "freetype_test"=.\freetype_test.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/freetype_test/freetype_test.vcxproj b/examples/win32_api/freetype_test/freetype_test.vcxproj new file mode 100644 index 0000000..720ccd8 --- /dev/null +++ b/examples/win32_api/freetype_test/freetype_test.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;../../../font_freetype;../../../../freetype2/include;../../../../freetype2/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\freetype_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\freetype_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\freetype_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\freetype_test.exe</OutputFile> + <AdditionalLibraryDirectories>../../../../freetype2/objs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;freetype219.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;../../../font_freetype;../../../../../freetype2/include;../../../../../freetype2/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\freetype_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\freetype_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\freetype_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\freetype_test.exe</OutputFile> + <AdditionalLibraryDirectories>../../../../../freetype2/objs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;freetype2411_D.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\font_freetype\agg_font_freetype.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\freetype_test.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\font_freetype\agg_font_freetype.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/freetype_test/readme b/examples/win32_api/freetype_test/readme new file mode 100644 index 0000000..4dd950b --- /dev/null +++ b/examples/win32_api/freetype_test/readme @@ -0,0 +1,9 @@ +This example demonstrates the use of the FreeType font rendering +engine (http://freetype.org). Please get file "timesi.ttf" before +running this example. You can copy timesi.zip from ..\..\art + +Note that the building environment expects +FreeType installed into the root directory, that is, "\freetype2". +It supposed to be compiled in "Debug" and "Release" configurations. +If you install FreeType somewhere else please correct the paths +to the include and library directories. diff --git a/examples/win32_api/gamma_correction/Makefile b/examples/win32_api/gamma_correction/Makefile new file mode 100644 index 0000000..05bb4a6 --- /dev/null +++ b/examples/win32_api/gamma_correction/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=gamma_correction +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/gamma_correction/gamma_correction.dsp b/examples/win32_api/gamma_correction/gamma_correction.dsp new file mode 100644 index 0000000..4b88e43 --- /dev/null +++ b/examples/win32_api/gamma_correction/gamma_correction.dsp @@ -0,0 +1,135 @@ +# Microsoft Developer Studio Project File - Name="gamma_correction" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=gamma_correction - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gamma_correction.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gamma_correction.mak" CFG="gamma_correction - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gamma_correction - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "gamma_correction - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gamma_correction - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"gamma_correction.exe" + +!ELSEIF "$(CFG)" == "gamma_correction - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gamma_correction - Win32 Release" +# Name "gamma_correction - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gamma_correction.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/gamma_correction/gamma_correction.dsw b/examples/win32_api/gamma_correction/gamma_correction.dsw new file mode 100644 index 0000000..9b88dbe --- /dev/null +++ b/examples/win32_api/gamma_correction/gamma_correction.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gamma_correction"=.\gamma_correction.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/gamma_correction/gamma_correction.vcxproj b/examples/win32_api/gamma_correction/gamma_correction.vcxproj new file mode 100644 index 0000000..e9afe74 --- /dev/null +++ b/examples/win32_api/gamma_correction/gamma_correction.vcxproj @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CB620C3E-E1AE-7256-A156-3D7DA1F6B389}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\gamma_correction.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\gamma_correction.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\gamma_correction.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>gamma_correction.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\gamma_correction.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\gamma_correction.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\gamma_correction.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\gamma_correction.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\gamma_correction.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/gamma_ctrl/Makefile b/examples/win32_api/gamma_ctrl/Makefile new file mode 100644 index 0000000..3a241d7 --- /dev/null +++ b/examples/win32_api/gamma_ctrl/Makefile @@ -0,0 +1,39 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=gamma_ctrl +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + diff --git a/examples/win32_api/gamma_ctrl/gamma_ctrl.dsp b/examples/win32_api/gamma_ctrl/gamma_ctrl.dsp new file mode 100644 index 0000000..03df54a --- /dev/null +++ b/examples/win32_api/gamma_ctrl/gamma_ctrl.dsp @@ -0,0 +1,145 @@ +# Microsoft Developer Studio Project File - Name="gamma_ctrl" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=gamma_ctrl - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gamma_ctrl.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gamma_ctrl.mak" CFG="gamma_ctrl - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gamma_ctrl - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "gamma_ctrl - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gamma_ctrl - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./gamma_ctrl.exe" +# SUBTRACT LINK32 /profile + +!ELSEIF "$(CFG)" == "gamma_ctrl - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gamma_ctrl - Win32 Release" +# Name "gamma_ctrl - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_gamma_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_gamma_spline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gamma_ctrl.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/gamma_ctrl/gamma_ctrl.dsw b/examples/win32_api/gamma_ctrl/gamma_ctrl.dsw new file mode 100644 index 0000000..d7bb4d9 --- /dev/null +++ b/examples/win32_api/gamma_ctrl/gamma_ctrl.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gamma_ctrl"=.\gamma_ctrl.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/gamma_ctrl/gamma_ctrl.vcxproj b/examples/win32_api/gamma_ctrl/gamma_ctrl.vcxproj new file mode 100644 index 0000000..d6937b8 --- /dev/null +++ b/examples/win32_api/gamma_ctrl/gamma_ctrl.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{3275483B-428E-AA1F-FCA7-79A473B09309}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\gamma_ctrl.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\gamma_ctrl.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\gamma_ctrl.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\gamma_ctrl.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\gamma_ctrl.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\gamma_ctrl.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\gamma_ctrl.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\gamma_ctrl.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_gamma_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_gamma_spline.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\gamma_ctrl.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/gamma_tuner/Makefile b/examples/win32_api/gamma_tuner/Makefile new file mode 100644 index 0000000..54cfe4d --- /dev/null +++ b/examples/win32_api/gamma_tuner/Makefile @@ -0,0 +1,39 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=gamma_tuner +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + diff --git a/examples/win32_api/gamma_tuner/gamma_tuner.dsp b/examples/win32_api/gamma_tuner/gamma_tuner.dsp new file mode 100644 index 0000000..2cb23f8 --- /dev/null +++ b/examples/win32_api/gamma_tuner/gamma_tuner.dsp @@ -0,0 +1,139 @@ +# Microsoft Developer Studio Project File - Name="gamma_tuner" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=gamma_tuner - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gamma_tuner.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gamma_tuner.mak" CFG="gamma_tuner - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gamma_tuner - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "gamma_tuner - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gamma_tuner - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"gamma_tuner.exe" + +!ELSEIF "$(CFG)" == "gamma_tuner - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gamma_tuner - Win32 Release" +# Name "gamma_tuner - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gamma_tuner.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/gamma_tuner/gamma_tuner.dsw b/examples/win32_api/gamma_tuner/gamma_tuner.dsw new file mode 100644 index 0000000..d9781aa --- /dev/null +++ b/examples/win32_api/gamma_tuner/gamma_tuner.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gamma_tuner"=.\gamma_tuner.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/gamma_tuner/gamma_tuner.vcxproj b/examples/win32_api/gamma_tuner/gamma_tuner.vcxproj new file mode 100644 index 0000000..5c4835f --- /dev/null +++ b/examples/win32_api/gamma_tuner/gamma_tuner.vcxproj @@ -0,0 +1,155 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6590D1BE-BEF8-6724-0334-3E729C64CC7A}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\gamma_tuner.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\gamma_tuner.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\gamma_tuner.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>gamma_tuner.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\gamma_tuner.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\gamma_tuner.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\gamma_tuner.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\gamma_tuner.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\gamma_tuner.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/gouraud/Makefile b/examples/win32_api/gouraud/Makefile new file mode 100644 index 0000000..37840ea --- /dev/null +++ b/examples/win32_api/gouraud/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=gouraud +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/gouraud/gouraud.dsp b/examples/win32_api/gouraud/gouraud.dsp new file mode 100644 index 0000000..babf4ed --- /dev/null +++ b/examples/win32_api/gouraud/gouraud.dsp @@ -0,0 +1,135 @@ +# Microsoft Developer Studio Project File - Name="gouraud" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=gouraud - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gouraud.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gouraud.mak" CFG="gouraud - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gouraud - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "gouraud - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gouraud - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./gouraud.exe" + +!ELSEIF "$(CFG)" == "gouraud - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gouraud - Win32 Release" +# Name "gouraud - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gouraud.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/gouraud/gouraud.dsw b/examples/win32_api/gouraud/gouraud.dsw new file mode 100644 index 0000000..1d9fb2c --- /dev/null +++ b/examples/win32_api/gouraud/gouraud.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gouraud"=.\gouraud.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/gouraud/gouraud.vcxproj b/examples/win32_api/gouraud/gouraud.vcxproj new file mode 100644 index 0000000..b3e4da0 --- /dev/null +++ b/examples/win32_api/gouraud/gouraud.vcxproj @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A4D74496-7313-3123-B26C-29B3C16D5ED6}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\gouraud.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\gouraud.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\gouraud.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\gouraud.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\gouraud.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\gouraud.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\gouraud.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\gouraud.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\gouraud.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/gouraud_mesh/Makefile b/examples/win32_api/gouraud_mesh/Makefile new file mode 100644 index 0000000..d0d9377 --- /dev/null +++ b/examples/win32_api/gouraud_mesh/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=gouraud_mesh +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/gouraud_mesh/gouraud_mesh.dsp b/examples/win32_api/gouraud_mesh/gouraud_mesh.dsp new file mode 100644 index 0000000..e54b70f --- /dev/null +++ b/examples/win32_api/gouraud_mesh/gouraud_mesh.dsp @@ -0,0 +1,155 @@ +# Microsoft Developer Studio Project File - Name="gouraud_mesh" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=gouraud_mesh - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gouraud_mesh.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gouraud_mesh.mak" CFG="gouraud_mesh - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gouraud_mesh - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "gouraud_mesh - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gouraud_mesh - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "AGG_FISTP" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./gouraud_mesh.exe" + +!ELSEIF "$(CFG)" == "gouraud_mesh - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "AGG_QIFIST" /YX /FD /GZ /QIfist /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gouraud_mesh - Win32 Release" +# Name "gouraud_mesh - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_polygon_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gouraud_mesh.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_rasterizer_sl_clip.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_gouraud_rgba.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/gouraud_mesh/gouraud_mesh.dsw b/examples/win32_api/gouraud_mesh/gouraud_mesh.dsw new file mode 100644 index 0000000..aa80282 --- /dev/null +++ b/examples/win32_api/gouraud_mesh/gouraud_mesh.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gouraud_mesh"=.\gouraud_mesh.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/gouraud_mesh/gouraud_mesh.vcxproj b/examples/win32_api/gouraud_mesh/gouraud_mesh.vcxproj new file mode 100644 index 0000000..44a0224 --- /dev/null +++ b/examples/win32_api/gouraud_mesh/gouraud_mesh.vcxproj @@ -0,0 +1,184 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{725B73C0-F3C8-D6E8-53D0-4C2418122ADB}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;AGG_FISTP;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\gouraud_mesh.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\gouraud_mesh.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\gouraud_mesh.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\gouraud_mesh.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;AGG_QIFIST;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\gouraud_mesh.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <AdditionalOptions> /QIfist </AdditionalOptions> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\gouraud_mesh.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\gouraud_mesh.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\gouraud_mesh.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + <ClCompile Include="..\..\..\src\agg_curves.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + <ClCompile Include="..\..\..\src\ctrl\agg_polygon_ctrl.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + <ClCompile Include="..\..\gouraud_mesh.cpp"> + <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> /QIfist /QIfist </AdditionalOptions> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_rasterizer_sl_clip.h" /> + <ClInclude Include="..\..\..\include\agg_span_gouraud_rgba.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/gpc_test/Makefile b/examples/win32_api/gpc_test/Makefile new file mode 100644 index 0000000..6a89af5 --- /dev/null +++ b/examples/win32_api/gpc_test/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=gpc_test +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include -I../../../gpc \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../make_arrows.cpp \ +../../make_gb_poly.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../*.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/gpc_test/gpc_test.dsp b/examples/win32_api/gpc_test/gpc_test.dsp new file mode 100644 index 0000000..5215b75 --- /dev/null +++ b/examples/win32_api/gpc_test/gpc_test.dsp @@ -0,0 +1,159 @@ +# Microsoft Developer Studio Project File - Name="gpc_test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=gpc_test - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gpc_test.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gpc_test.mak" CFG="gpc_test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gpc_test - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "gpc_test - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gpc_test - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /I "../../../gpc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./gpc_test.exe" + +!ELSEIF "$(CFG)" == "gpc_test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../gpc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gpc_test - Win32 Release" +# Name "gpc_test - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\gpc\gpc.c +# End Source File +# Begin Source File + +SOURCE=..\..\gpc_test.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\make_arrows.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\make_gb_poly.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/gpc_test/gpc_test.dsw b/examples/win32_api/gpc_test/gpc_test.dsw new file mode 100644 index 0000000..47eddaf --- /dev/null +++ b/examples/win32_api/gpc_test/gpc_test.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gpc_test"=.\gpc_test.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/gpc_test/gpc_test.vcxproj b/examples/win32_api/gpc_test/gpc_test.vcxproj new file mode 100644 index 0000000..71f0902 --- /dev/null +++ b/examples/win32_api/gpc_test/gpc_test.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{DB31FBEA-2DBD-BBEA-9F56-5C61BD3767C0}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;../../../gpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\gpc_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\gpc_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\gpc_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\gpc_test.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;../../../gpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\gpc_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\gpc_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\gpc_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\gpc_test.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\..\gpc\gpc.c" /> + <ClCompile Include="..\..\gpc_test.cpp" /> + <ClCompile Include="..\..\make_arrows.cpp" /> + <ClCompile Include="..\..\make_gb_poly.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/gradient_focal/Makefile b/examples/win32_api/gradient_focal/Makefile new file mode 100644 index 0000000..6aa607f --- /dev/null +++ b/examples/win32_api/gradient_focal/Makefile @@ -0,0 +1,38 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=gradient_focal +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/gradient_focal/gradient_focal.dsp b/examples/win32_api/gradient_focal/gradient_focal.dsp new file mode 100644 index 0000000..1fb9200 --- /dev/null +++ b/examples/win32_api/gradient_focal/gradient_focal.dsp @@ -0,0 +1,163 @@ +# Microsoft Developer Studio Project File - Name="gradient_focal" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=gradient_focal - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gradient_focal.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gradient_focal.mak" CFG="gradient_focal - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gradient_focal - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "gradient_focal - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gradient_focal - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /I "../../../gpc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./gradient_focal.exe" + +!ELSEIF "$(CFG)" == "gradient_focal - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../gpc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gradient_focal - Win32 Release" +# Name "gradient_focal - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gradient_focal.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_gradient_lut.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_image_filters.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/gradient_focal/gradient_focal.dsw b/examples/win32_api/gradient_focal/gradient_focal.dsw new file mode 100644 index 0000000..f524760 --- /dev/null +++ b/examples/win32_api/gradient_focal/gradient_focal.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gradient_focal"=.\gradient_focal.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/gradient_focal/gradient_focal.vcxproj b/examples/win32_api/gradient_focal/gradient_focal.vcxproj new file mode 100644 index 0000000..9666ad6 --- /dev/null +++ b/examples/win32_api/gradient_focal/gradient_focal.vcxproj @@ -0,0 +1,165 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{E3EEAEFA-0BA7-E6CE-C651-98A48D0C9075}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;../../../gpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\gradient_focal.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\gradient_focal.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\gradient_focal.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\gradient_focal.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;../../../gpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\gradient_focal.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\gradient_focal.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\gradient_focal.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\gradient_focal.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\gradient_focal.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_gradient_lut.h" /> + <ClInclude Include="..\..\..\include\agg_image_filters.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/gradients/Makefile b/examples/win32_api/gradients/Makefile new file mode 100644 index 0000000..e7be5c8 --- /dev/null +++ b/examples/win32_api/gradients/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=gradients +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/gradients/gradients.dsp b/examples/win32_api/gradients/gradients.dsp new file mode 100644 index 0000000..49e3d44 --- /dev/null +++ b/examples/win32_api/gradients/gradients.dsp @@ -0,0 +1,165 @@ +# Microsoft Developer Studio Project File - Name="gradients" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=gradients - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gradients.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gradients.mak" CFG="gradients - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gradients - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "gradients - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gradients - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./gradients.exe" + +!ELSEIF "$(CFG)" == "gradients - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "gradients - Win32 Release" +# Name "gradients - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_gamma_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_gamma_spline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_spline_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\gradients.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/gradients/gradients.dsw b/examples/win32_api/gradients/gradients.dsw new file mode 100644 index 0000000..81e694b --- /dev/null +++ b/examples/win32_api/gradients/gradients.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gradients"=.\gradients.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/gradients/gradients.vcxproj b/examples/win32_api/gradients/gradients.vcxproj new file mode 100644 index 0000000..1dcdf24 --- /dev/null +++ b/examples/win32_api/gradients/gradients.vcxproj @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{44FB9161-7404-16D4-B571-5CB85384B609}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\gradients.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\gradients.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\gradients.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\gradients.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\gradients.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\gradients.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\gradients.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\gradients.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_gamma_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_gamma_spline.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_spline_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\gradients.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/gradients/settings.dat b/examples/win32_api/gradients/settings.dat new file mode 100644 index 0000000..d0e6c17 --- /dev/null +++ b/examples/win32_api/gradients/settings.dat @@ -0,0 +1,56 @@ +399.254028 +339.996429 +1.128661 +77.270996 +0.000000 +1.000000 +0.115323 +1.000000 +0.363710 +0.812121 +0.604032 +0.460606 +0.791935 +0.200000 +1.000000 +0.606061 +0.000000 +1.000000 +0.083065 +1.000000 +0.299194 +0.418182 +0.651484 +0.000000 +0.810365 +0.000000 +1.000000 +0.290598 +0.000000 +1.000000 +0.051755 +0.934195 +0.115509 +0.587701 +0.334362 +0.000000 +0.708762 +0.000000 +1.000000 +0.000000 +0.000000 +1.000000 +0.171775 +1.000000 +0.376360 +1.000000 +0.598100 +1.000000 +0.804839 +1.000000 +1.000000 +1.000000 +0.786681 +1.239889 +0.726049 +0.710140 diff --git a/examples/win32_api/graph_test/Makefile b/examples/win32_api/graph_test/Makefile new file mode 100644 index 0000000..4f87197 --- /dev/null +++ b/examples/win32_api/graph_test/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=graph_test +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/graph_test/graph_test.dsp b/examples/win32_api/graph_test/graph_test.dsp new file mode 100644 index 0000000..2827b41 --- /dev/null +++ b/examples/win32_api/graph_test/graph_test.dsp @@ -0,0 +1,180 @@ +# Microsoft Developer Studio Project File - Name="graph_test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=graph_test - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "graph_test.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "graph_test.mak" CFG="graph_test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "graph_test - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "graph_test - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "graph_test - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./graph_test.exe" +# SUBTRACT LINK32 /profile + +!ELSEIF "$(CFG)" == "graph_test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "graph_test - Win32 Release" +# Name "graph_test - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_arrowhead.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_rounded_rect.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_dash.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_markers_term.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_smooth_poly1.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\graph_test.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/graph_test/graph_test.dsw b/examples/win32_api/graph_test/graph_test.dsw new file mode 100644 index 0000000..b6989e7 --- /dev/null +++ b/examples/win32_api/graph_test/graph_test.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "graph_test"=.\graph_test.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/graph_test/graph_test.vcxproj b/examples/win32_api/graph_test/graph_test.vcxproj new file mode 100644 index 0000000..e984edb --- /dev/null +++ b/examples/win32_api/graph_test/graph_test.vcxproj @@ -0,0 +1,165 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{9A22718A-2B37-9BB2-3064-E04B5B92D1E7}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\graph_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\graph_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\graph_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\graph_test.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\graph_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\graph_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\graph_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\graph_test.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_arrowhead.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_rounded_rect.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_dash.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_markers_term.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_smooth_poly1.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\graph_test.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/idea/Makefile b/examples/win32_api/idea/Makefile new file mode 100644 index 0000000..9061c9f --- /dev/null +++ b/examples/win32_api/idea/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=idea +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/idea/idea.dsp b/examples/win32_api/idea/idea.dsp new file mode 100644 index 0000000..beafec5 --- /dev/null +++ b/examples/win32_api/idea/idea.dsp @@ -0,0 +1,141 @@ +# Microsoft Developer Studio Project File - Name="idea" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=idea - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "idea.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "idea.mak" CFG="idea - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "idea - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "idea - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "idea - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./idea.exe" + +!ELSEIF "$(CFG)" == "idea - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "idea - Win32 Release" +# Name "idea - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\idea.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/idea/idea.dsw b/examples/win32_api/idea/idea.dsw new file mode 100644 index 0000000..0dda051 --- /dev/null +++ b/examples/win32_api/idea/idea.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "idea"=.\idea.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/idea/idea.vcxproj b/examples/win32_api/idea/idea.vcxproj new file mode 100644 index 0000000..b639d7c --- /dev/null +++ b/examples/win32_api/idea/idea.vcxproj @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{46BE7D0C-99BE-5EB2-D451-5761CBC7BAEF}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\idea.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\idea.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\idea.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\idea.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\idea.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\idea.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\idea.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\idea.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\idea.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/image1/Makefile b/examples/win32_api/image1/Makefile new file mode 100644 index 0000000..d1d3f7d --- /dev/null +++ b/examples/win32_api/image1/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=image1 +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/image1/image1.dsp b/examples/win32_api/image1/image1.dsp new file mode 100644 index 0000000..ceed7ad --- /dev/null +++ b/examples/win32_api/image1/image1.dsp @@ -0,0 +1,153 @@ +# Microsoft Developer Studio Project File - Name="image1" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=image1 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "image1.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "image1.mak" CFG="image1 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "image1 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "image1 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "image1 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./image1.exe" +# SUBTRACT LINK32 /profile + +!ELSEIF "$(CFG)" == "image1 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "image1 - Win32 Release" +# Name "image1 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_spline_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\image1.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/image1/image1.dsw b/examples/win32_api/image1/image1.dsw new file mode 100644 index 0000000..3905d44 --- /dev/null +++ b/examples/win32_api/image1/image1.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "image1"=.\image1.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/image1/image1.vcxproj b/examples/win32_api/image1/image1.vcxproj new file mode 100644 index 0000000..14c4ec6 --- /dev/null +++ b/examples/win32_api/image1/image1.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A58FEE69-867D-1FF4-62BE-6F58020624D0}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\image1.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\image1.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\image1.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\image1.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\image1.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\image1.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\image1.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\image1.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_spline_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\image1.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/image1/readme b/examples/win32_api/image1/readme new file mode 100644 index 0000000..ec93123 --- /dev/null +++ b/examples/win32_api/image1/readme @@ -0,0 +1 @@ +Copy spheres.bmp from ..\..\art before running this example \ No newline at end of file diff --git a/examples/win32_api/image_alpha/Makefile b/examples/win32_api/image_alpha/Makefile new file mode 100644 index 0000000..7d70f3c --- /dev/null +++ b/examples/win32_api/image_alpha/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=image_alpha +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/image_alpha/image_alpha.dsp b/examples/win32_api/image_alpha/image_alpha.dsp new file mode 100644 index 0000000..508d925 --- /dev/null +++ b/examples/win32_api/image_alpha/image_alpha.dsp @@ -0,0 +1,149 @@ +# Microsoft Developer Studio Project File - Name="image_alpha" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=image_alpha - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "image_alpha.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "image_alpha.mak" CFG="image_alpha - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "image_alpha - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "image_alpha - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "image_alpha - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./image_alpha.exe" +# SUBTRACT LINK32 /profile + +!ELSEIF "$(CFG)" == "image_alpha - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "image_alpha - Win32 Release" +# Name "image_alpha - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_spline_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\image_alpha.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/image_alpha/image_alpha.dsw b/examples/win32_api/image_alpha/image_alpha.dsw new file mode 100644 index 0000000..4fde136 --- /dev/null +++ b/examples/win32_api/image_alpha/image_alpha.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "image_alpha"=.\image_alpha.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/image_alpha/image_alpha.vcxproj b/examples/win32_api/image_alpha/image_alpha.vcxproj new file mode 100644 index 0000000..03a7ae0 --- /dev/null +++ b/examples/win32_api/image_alpha/image_alpha.vcxproj @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EC41EC41-BEC3-B108-A96C-304F123869D3}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\image_alpha.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\image_alpha.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\image_alpha.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\image_alpha.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\image_alpha.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\image_alpha.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\image_alpha.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\image_alpha.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_spline_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\image_alpha.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/image_alpha/readme b/examples/win32_api/image_alpha/readme new file mode 100644 index 0000000..8aa5db7 --- /dev/null +++ b/examples/win32_api/image_alpha/readme @@ -0,0 +1 @@ +Copy spheres.bmp from ..\..\art before running this example. diff --git a/examples/win32_api/image_filters/Makefile b/examples/win32_api/image_filters/Makefile new file mode 100644 index 0000000..9dba1af --- /dev/null +++ b/examples/win32_api/image_filters/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=image_filters +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/image_filters/image_filters.dsp b/examples/win32_api/image_filters/image_filters.dsp new file mode 100644 index 0000000..b0131e7 --- /dev/null +++ b/examples/win32_api/image_filters/image_filters.dsp @@ -0,0 +1,173 @@ +# Microsoft Developer Studio Project File - Name="image_filters" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=image_filters - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "image_filters.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "image_filters.mak" CFG="image_filters - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "image_filters - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "image_filters - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "image_filters - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./image_filters.exe" +# SUBTRACT LINK32 /profile + +!ELSEIF "$(CFG)" == "image_filters - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "image_filters - Win32 Release" +# Name "image_filters - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_spline_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\image_filters.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_gray.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_rgb.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_rgba.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/image_filters/image_filters.dsw b/examples/win32_api/image_filters/image_filters.dsw new file mode 100644 index 0000000..eb5813e --- /dev/null +++ b/examples/win32_api/image_filters/image_filters.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "image_filters"=.\image_filters.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/image_filters/image_filters.vcxproj b/examples/win32_api/image_filters/image_filters.vcxproj new file mode 100644 index 0000000..d5faab9 --- /dev/null +++ b/examples/win32_api/image_filters/image_filters.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{FBFDF907-772D-20C1-B966-7AA299DEE301}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\image_filters.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\image_filters.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\image_filters.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\image_filters.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\image_filters.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\image_filters.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\image_filters.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\image_filters.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_spline_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\image_filters.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_span_image_filter_gray.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter_rgb.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter_rgba.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/image_filters/readme b/examples/win32_api/image_filters/readme new file mode 100644 index 0000000..8aa5db7 --- /dev/null +++ b/examples/win32_api/image_filters/readme @@ -0,0 +1 @@ +Copy spheres.bmp from ..\..\art before running this example. diff --git a/examples/win32_api/image_filters2/Makefile b/examples/win32_api/image_filters2/Makefile new file mode 100644 index 0000000..4164ee9 --- /dev/null +++ b/examples/win32_api/image_filters2/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=image_filters2 +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/image_filters2/image_filters2.dsp b/examples/win32_api/image_filters2/image_filters2.dsp new file mode 100644 index 0000000..5b83bd2 --- /dev/null +++ b/examples/win32_api/image_filters2/image_filters2.dsp @@ -0,0 +1,161 @@ +# Microsoft Developer Studio Project File - Name="image_filters2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=image_filters2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "image_filters2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "image_filters2.mak" CFG="image_filters2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "image_filters2 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "image_filters2 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "image_filters2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./image_filters2.exe" +# SUBTRACT LINK32 /profile + +!ELSEIF "$(CFG)" == "image_filters2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "image_filters2 - Win32 Release" +# Name "image_filters2 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_spline_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\image_filters2.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/image_filters2/image_filters2.dsw b/examples/win32_api/image_filters2/image_filters2.dsw new file mode 100644 index 0000000..fcc168f --- /dev/null +++ b/examples/win32_api/image_filters2/image_filters2.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "image_filters2"=.\image_filters2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/image_filters2/image_filters2.vcxproj b/examples/win32_api/image_filters2/image_filters2.vcxproj new file mode 100644 index 0000000..0d1771e --- /dev/null +++ b/examples/win32_api/image_filters2/image_filters2.vcxproj @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{67D784F4-AE57-86EF-85CB-9EC6CADFF616}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\image_filters2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\image_filters2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\image_filters2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\image_filters2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\image_filters2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\image_filters2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\image_filters2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\image_filters2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_spline_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\image_filters2.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/image_filters2/readme b/examples/win32_api/image_filters2/readme new file mode 100644 index 0000000..8aa5db7 --- /dev/null +++ b/examples/win32_api/image_filters2/readme @@ -0,0 +1 @@ +Copy spheres.bmp from ..\..\art before running this example. diff --git a/examples/win32_api/image_fltr_graph/Makefile b/examples/win32_api/image_fltr_graph/Makefile new file mode 100644 index 0000000..92593b4 --- /dev/null +++ b/examples/win32_api/image_fltr_graph/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=image_fltr_graph +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/image_fltr_graph/image_fltr_graph.dsp b/examples/win32_api/image_fltr_graph/image_fltr_graph.dsp new file mode 100644 index 0000000..f69d424 --- /dev/null +++ b/examples/win32_api/image_fltr_graph/image_fltr_graph.dsp @@ -0,0 +1,169 @@ +# Microsoft Developer Studio Project File - Name="image_fltr_graph" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=image_fltr_graph - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "image_fltr_graph.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "image_fltr_graph.mak" CFG="image_fltr_graph - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "image_fltr_graph - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "image_fltr_graph - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "image_fltr_graph - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./image_fltr_graph.exe" +# SUBTRACT LINK32 /profile + +!ELSEIF "$(CFG)" == "image_fltr_graph - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "image_fltr_graph - Win32 Release" +# Name "image_fltr_graph - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_spline_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\image_fltr_graph.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_span_bgra32_image.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\..\include\agg_gouraud_attr.h +# End Source File +# End Target +# End Project diff --git a/examples/win32_api/image_fltr_graph/image_fltr_graph.dsw b/examples/win32_api/image_fltr_graph/image_fltr_graph.dsw new file mode 100644 index 0000000..3705197 --- /dev/null +++ b/examples/win32_api/image_fltr_graph/image_fltr_graph.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "image_fltr_graph"=.\image_fltr_graph.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/image_fltr_graph/image_fltr_graph.vcxproj b/examples/win32_api/image_fltr_graph/image_fltr_graph.vcxproj new file mode 100644 index 0000000..dfd96de --- /dev/null +++ b/examples/win32_api/image_fltr_graph/image_fltr_graph.vcxproj @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{7CB77339-97A9-1507-BF82-11BD57A3733B}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\image_fltr_graph.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\image_fltr_graph.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\image_fltr_graph.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\image_fltr_graph.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\image_fltr_graph.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\image_fltr_graph.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\image_fltr_graph.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\image_fltr_graph.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_spline_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\image_fltr_graph.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_span_bgra32_image.h" /> + <ClInclude Include="..\..\..\include\agg_gouraud_attr.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/image_perspective/Makefile b/examples/win32_api/image_perspective/Makefile new file mode 100644 index 0000000..91025f4 --- /dev/null +++ b/examples/win32_api/image_perspective/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=image_perspective +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../interactive_polygon.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../interactive_polygon.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/image_perspective/image_perspective.dsp b/examples/win32_api/image_perspective/image_perspective.dsp new file mode 100644 index 0000000..c96cc23 --- /dev/null +++ b/examples/win32_api/image_perspective/image_perspective.dsp @@ -0,0 +1,151 @@ +# Microsoft Developer Studio Project File - Name="image_perspective" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=image_perspective - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "image_perspective.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "image_perspective.mak" CFG="image_perspective - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "image_perspective - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "image_perspective - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "image_perspective - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./image_perspective.exe" + +!ELSEIF "$(CFG)" == "image_perspective - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "image_perspective - Win32 Release" +# Name "image_perspective - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\image_perspective.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\interactive_polygon.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_image_accessors.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_pixfmt_rgba.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/image_perspective/image_perspective.dsw b/examples/win32_api/image_perspective/image_perspective.dsw new file mode 100644 index 0000000..acf817f --- /dev/null +++ b/examples/win32_api/image_perspective/image_perspective.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "image_perspective"=.\image_perspective.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/image_perspective/image_perspective.vcxproj b/examples/win32_api/image_perspective/image_perspective.vcxproj new file mode 100644 index 0000000..b293a37 --- /dev/null +++ b/examples/win32_api/image_perspective/image_perspective.vcxproj @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CCCB62D2-F473-1858-6280-12EB5371C317}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\image_perspective.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\image_perspective.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\image_perspective.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\image_perspective.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\image_perspective.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\image_perspective.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\image_perspective.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\image_perspective.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\image_perspective.cpp" /> + <ClCompile Include="..\..\interactive_polygon.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_image_accessors.h" /> + <ClInclude Include="..\..\..\include\agg_pixfmt_rgba.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/image_perspective/readme b/examples/win32_api/image_perspective/readme new file mode 100644 index 0000000..8aa5db7 --- /dev/null +++ b/examples/win32_api/image_perspective/readme @@ -0,0 +1 @@ +Copy spheres.bmp from ..\..\art before running this example. diff --git a/examples/win32_api/image_resample/Makefile b/examples/win32_api/image_resample/Makefile new file mode 100644 index 0000000..267efa4 --- /dev/null +++ b/examples/win32_api/image_resample/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=image_resample +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../interactive_polygon.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../interactive_polygon.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/image_resample/image_resample.dsp b/examples/win32_api/image_resample/image_resample.dsp new file mode 100644 index 0000000..77a6385 --- /dev/null +++ b/examples/win32_api/image_resample/image_resample.dsp @@ -0,0 +1,187 @@ +# Microsoft Developer Studio Project File - Name="image_resample" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=image_resample - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "image_resample.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "image_resample.mak" CFG="image_resample - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "image_resample - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "image_resample - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "image_resample - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./image_resample.exe" + +!ELSEIF "$(CFG)" == "image_resample - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "image_resample - Win32 Release" +# Name "image_resample - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_bezier_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_polygon_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\image_resample.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\interactive_polygon.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_color_gray.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_gray.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_rgb.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_rgba.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_interpolator_persp.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_subdiv_adaptor.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/image_resample/image_resample.dsw b/examples/win32_api/image_resample/image_resample.dsw new file mode 100644 index 0000000..c1363fd --- /dev/null +++ b/examples/win32_api/image_resample/image_resample.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "image_resample"=.\image_resample.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/image_resample/image_resample.vcxproj b/examples/win32_api/image_resample/image_resample.vcxproj new file mode 100644 index 0000000..3159828 --- /dev/null +++ b/examples/win32_api/image_resample/image_resample.vcxproj @@ -0,0 +1,171 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{FEF6FDB5-5924-A2DC-1A94-C6ABD36DA709}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\image_resample.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\image_resample.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\image_resample.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\image_resample.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\image_resample.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\image_resample.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\image_resample.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\image_resample.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_bezier_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_polygon_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\image_resample.cpp" /> + <ClCompile Include="..\..\interactive_polygon.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_color_gray.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter_gray.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter_rgb.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter_rgba.h" /> + <ClInclude Include="..\..\..\include\agg_span_interpolator_persp.h" /> + <ClInclude Include="..\..\..\include\agg_span_subdiv_adaptor.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/image_resample/readme b/examples/win32_api/image_resample/readme new file mode 100644 index 0000000..8aa5db7 --- /dev/null +++ b/examples/win32_api/image_resample/readme @@ -0,0 +1 @@ +Copy spheres.bmp from ..\..\art before running this example. diff --git a/examples/win32_api/image_transforms/Makefile b/examples/win32_api/image_transforms/Makefile new file mode 100644 index 0000000..1d88d45 --- /dev/null +++ b/examples/win32_api/image_transforms/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=image_transforms +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/image_transforms/image_transforms.dsp b/examples/win32_api/image_transforms/image_transforms.dsp new file mode 100644 index 0000000..bcaed82 --- /dev/null +++ b/examples/win32_api/image_transforms/image_transforms.dsp @@ -0,0 +1,173 @@ +# Microsoft Developer Studio Project File - Name="image_transforms" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=image_transforms - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "image_transforms.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "image_transforms.mak" CFG="image_transforms - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "image_transforms - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "image_transforms - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "image_transforms - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./image_transforms.exe" +# SUBTRACT LINK32 /profile + +!ELSEIF "$(CFG)" == "image_transforms - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "image_transforms - Win32 Release" +# Name "image_transforms - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_spline_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\image_transforms.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_rgb24.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_rgba32.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# Begin Source File + +SOURCE=..\..\..\include\agg_gouraud_attr.h +# End Source File +# End Target +# End Project diff --git a/examples/win32_api/image_transforms/image_transforms.dsw b/examples/win32_api/image_transforms/image_transforms.dsw new file mode 100644 index 0000000..4dbf442 --- /dev/null +++ b/examples/win32_api/image_transforms/image_transforms.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "image_transforms"=.\image_transforms.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/image_transforms/image_transforms.vcxproj b/examples/win32_api/image_transforms/image_transforms.vcxproj new file mode 100644 index 0000000..8544f7a --- /dev/null +++ b/examples/win32_api/image_transforms/image_transforms.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{AF5A05DD-6CB3-2060-5748-14E4FC2AEC19}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\image_transforms.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\image_transforms.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\image_transforms.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\image_transforms.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\image_transforms.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\image_transforms.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\image_transforms.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\image_transforms.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_spline_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\image_transforms.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_span_image_filter_rgb24.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter_rgba32.h" /> + <ClInclude Include="..\..\..\include\agg_gouraud_attr.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/image_transforms/readme! b/examples/win32_api/image_transforms/readme! new file mode 100644 index 0000000..f7241bb --- /dev/null +++ b/examples/win32_api/image_transforms/readme! @@ -0,0 +1,189 @@ +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- + +IMPORTANT! +Copy spheres.bmp from ..\..\art before running this example. + + +Using affine transformations for images looks tricky, but it's not, especially +when you understand the main idea. You can apply any affine transformations +to images of any size and draw any part of the image. + +This example demonstrates the ideas of constructing affine matrices for +images. The example contains 6 variants of scaling/rotation/translation +matrices. Also, there are the following important variables: + +m_polygon_angle; +m_polygon_scale; + +m_image_angle; +m_image_scale; + +m_image_center_x; +m_image_center_y; + +m_polygon_cx; +m_polygon_cy; + +m_image_cx; +m_image_cy; + + +Variables m_polygon_... refer to the source path (star) that will be used to +transform the image, variables m_image_... refer to the image parametres. +Actually, different variants of transformations use different variables +(in some cases m_polygon_... is used to create the image affine matrix). +The meaning of the variables is the following: + +m_polygon_angle; +m_polygon_scale; + +Are actually two slider controls on the left. + +m_polygon_cx; +m_polygon_cy; + +Are the center of the "star", that is the geometric center of the source path. +You can drag the "star" with the left mouse button. + +m_image_angle; +m_image_scale; + +are two respective sliders on the right. + +m_image_cx; +m_image_cy; + +are the coordinates of the green marker. The marker can also be dragged. + +m_image_center_x; +m_image_center_y; + +are the center of the image. You can consider them as constants. +In certain cases it's easier to understand the idea when we have some +"reference point", like the center or the origin of the axes. + +The image transformation matrix doesn't depend on anything else. +It means that the code above the line "// --------------(Example 0)": + + 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); + +affects only the drawn path. So, the only way to shift, rotate, or scale the +image is to use the image affine matrix (image_mtx in this example). + +Another important thing is that due to the nature of the algorithm you +have to use the inverse transformations. The algorithm takes the +coordinates of every destination pixel, applies the transformations and +obtains the coordinates of the pixel to pick it up from the source image. +The coordinates of the destination pixels are always known and they have +regular, pixel accuracy. After transforming they usually fall somewhere " +between" pixels. This fact allows us to apply anti-aliasing filters like +bilinear, bicubic, sinc, blackman, etc. After filtering we know the value of the +destination pixel and we can put it in its place. This is why the algorithm +uses the inverse affine matrix. In other words you prepare the transformation +matrix as usual and then invret it before using: + + 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(); + +This code illustrates the behaviour when we have synchronous transformations +of the source path and the image. + +Well, let us return to example 0. Here we have a "star" that can be dragged with +the left mouse button, a small round green marker, and four sliders. +The marker and the sliders on the right don't affect anything. As it was said, +this example simply copies pixels from the source image to the destination canvas. + +Example 1. The marker and the image sliders on the right still +don't work, but now the image is moved, scaled, and rotated syncronously with +the "star". We simply take the reference point, which is m_image_center_x(y), +rotate and scale the image around it, and then, translate the image to +m_polygon_cx(cy). + + +Example 2 is the same as 1 but instead of using "m_polygon_..." parameters we +use "m_image_..." ones, so the marker and the sliders on the right now work +independently. In other words you can control the image and the "star" separately. + 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(); + + +Example 3 is the same as the above but instead of using "m_image_cx(cy)" we use +m_polygon_cx(cy). So that, the image is rotated and scaled around its center, +but the marker doesn't have any effect. + 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(); + + +Example 4 is the same as 1, but we use m_image_cx(cy) as the source point +in the image. So, the image sliders don't work, the image is transformed +synchronously with the path, but we are able to choose the source point for +image transformations. That is the idea: we take the source point in the +image, perform the transformations around it and then move this source +point to the center of the "star". + 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(); + + +Example 5 is the same as 2, but there we have a combination of the scaling +and rotation of the "star" and the image. + 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(); +BTW, code above can be simplified like this: + 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 + + m_polygon_angle.value() * agg::pi / 180.0); + image_mtx *= agg::trans_affine_scaling(m_image_scale.value() * m_polygon_scale.value()); + image_mtx *= agg::trans_affine_translation(m_image_cx, m_image_cy); + image_mtx.invert(); + + +Finally, example 5 is probably not very interesting in practice, but still, it +can simplify understanding of the idea. This example uses only m_image_... +parameters. It shifts the image from m_image_cx(cy) to the origin (0,0), then +applies rotation and scaling, and finally, shifts the image back. So that, +point m_image_cx(cy) is simply the center of the transformations. When the +image angle is 0.0 and the scale is 1.0 dragging this point doesn't have any +effect. + 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(); + + +Many thank to you if you read it and many special thanks if you could understand +something. :-) + diff --git a/examples/win32_api/line_patterns/Makefile b/examples/win32_api/line_patterns/Makefile new file mode 100644 index 0000000..19483a9 --- /dev/null +++ b/examples/win32_api/line_patterns/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=line_patterns +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/line_patterns/line_patterns.dsp b/examples/win32_api/line_patterns/line_patterns.dsp new file mode 100644 index 0000000..550f054 --- /dev/null +++ b/examples/win32_api/line_patterns/line_patterns.dsp @@ -0,0 +1,163 @@ +# Microsoft Developer Studio Project File - Name="line_patterns" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=line_patterns - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "line_patterns.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "line_patterns.mak" CFG="line_patterns - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "line_patterns - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "line_patterns - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "line_patterns - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./line_patterns.exe" + +!ELSEIF "$(CFG)" == "line_patterns - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "line_patterns - Win32 Release" +# Name "line_patterns - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_bezier_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_aa_basics.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_profile_aa.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_polygon_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\line_patterns.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/line_patterns/line_patterns.dsw b/examples/win32_api/line_patterns/line_patterns.dsw new file mode 100644 index 0000000..5c2a387 --- /dev/null +++ b/examples/win32_api/line_patterns/line_patterns.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "line_patterns"=.\line_patterns.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/line_patterns/line_patterns.vcxproj b/examples/win32_api/line_patterns/line_patterns.vcxproj new file mode 100644 index 0000000..8c37a95 --- /dev/null +++ b/examples/win32_api/line_patterns/line_patterns.vcxproj @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{1AC06016-EA58-2079-0D9E-E85B198188B6}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\line_patterns.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\line_patterns.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\line_patterns.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\line_patterns.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\line_patterns.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\line_patterns.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\line_patterns.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\line_patterns.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_bezier_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_aa_basics.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_profile_aa.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_polygon_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\line_patterns.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/line_patterns_clip/Makefile b/examples/win32_api/line_patterns_clip/Makefile new file mode 100644 index 0000000..60d8a13 --- /dev/null +++ b/examples/win32_api/line_patterns_clip/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=line_patterns_clip +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/line_patterns_clip/line_patterns_clip.dsp b/examples/win32_api/line_patterns_clip/line_patterns_clip.dsp new file mode 100644 index 0000000..e6e998c --- /dev/null +++ b/examples/win32_api/line_patterns_clip/line_patterns_clip.dsp @@ -0,0 +1,167 @@ +# Microsoft Developer Studio Project File - Name="line_patterns_clip" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=line_patterns_clip - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "line_patterns_clip.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "line_patterns_clip.mak" CFG="line_patterns_clip - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "line_patterns_clip - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "line_patterns_clip - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "line_patterns_clip - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./line_patterns_clip.exe" + +!ELSEIF "$(CFG)" == "line_patterns_clip - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "line_patterns_clip - Win32 Release" +# Name "line_patterns_clip - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_bezier_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_aa_basics.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_profile_aa.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_polygon_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vpgen_clip_polyline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\line_patterns_clip.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/line_patterns_clip/line_patterns_clip.dsw b/examples/win32_api/line_patterns_clip/line_patterns_clip.dsw new file mode 100644 index 0000000..0fa9f50 --- /dev/null +++ b/examples/win32_api/line_patterns_clip/line_patterns_clip.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "line_patterns_clip"=.\line_patterns_clip.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/line_patterns_clip/line_patterns_clip.vcxproj b/examples/win32_api/line_patterns_clip/line_patterns_clip.vcxproj new file mode 100644 index 0000000..cb5aa53 --- /dev/null +++ b/examples/win32_api/line_patterns_clip/line_patterns_clip.vcxproj @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B7F52AEF-C4E7-049C-3C28-902A52C24D9D}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\line_patterns_clip.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\line_patterns_clip.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\line_patterns_clip.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\line_patterns_clip.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\line_patterns_clip.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\line_patterns_clip.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\line_patterns_clip.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\line_patterns_clip.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_bezier_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_aa_basics.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_profile_aa.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_polygon_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\agg_vpgen_clip_polyline.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\line_patterns_clip.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/line_thickness/line_thickness.vcxproj b/examples/win32_api/line_thickness/line_thickness.vcxproj new file mode 100644 index 0000000..d4e6861 --- /dev/null +++ b/examples/win32_api/line_thickness/line_thickness.vcxproj @@ -0,0 +1,199 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{5E787227-E9A9-4839-AD18-6CDC16C6D1A6}</ProjectGuid> + <RootNamespace>aa_demo</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> + <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" /> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Midl> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MkTypLibCompatible>true</MkTypLibCompatible> + <SuppressStartupBanner>true</SuppressStartupBanner> + <TargetEnvironment>Win32</TargetEnvironment> + <TypeLibraryName>.\Release/aa_demo.tlb</TypeLibraryName> + <HeaderFileName> + </HeaderFileName> + </Midl> + <ClCompile> + <Optimization>MaxSpeed</Optimization> + <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeaderOutputFile>.\Release/aa_demo.pch</PrecompiledHeaderOutputFile> + <AssemblerListingLocation>.\Release/</AssemblerListingLocation> + <ObjectFileName>.\Release/</ObjectFileName> + <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <SuppressStartupBanner>true</SuppressStartupBanner> + <IntrinsicFunctions>true</IntrinsicFunctions> + <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> + <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet> + <WholeProgramOptimization>true</WholeProgramOptimization> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <Culture>0x0409</Culture> + </ResourceCompile> + <Link> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <SuppressStartupBanner>true</SuppressStartupBanner> + <ProgramDatabaseFile>.\Release/aa_demo.pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <TargetMachine>MachineX86</TargetMachine> + <GenerateDebugInformation>true</GenerateDebugInformation> + <Profile>true</Profile> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> + </Link> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release/aa_demo.bsc</OutputFile> + </Bscmake> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Midl> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MkTypLibCompatible>true</MkTypLibCompatible> + <SuppressStartupBanner>true</SuppressStartupBanner> + <TargetEnvironment>Win32</TargetEnvironment> + <TypeLibraryName>.\Debug/aa_demo.tlb</TypeLibraryName> + <HeaderFileName> + </HeaderFileName> + </Midl> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>true</MinimalRebuild> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <PrecompiledHeaderOutputFile>.\Debug/aa_demo.pch</PrecompiledHeaderOutputFile> + <AssemblerListingLocation>.\Debug/</AssemblerListingLocation> + <ObjectFileName>.\Debug/</ObjectFileName> + <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName> + <WarningLevel>Level3</WarningLevel> + <SuppressStartupBanner>true</SuppressStartupBanner> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <Culture>0x0409</Culture> + </ResourceCompile> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>.\Debug/aa_demo.pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <TargetMachine>MachineX86</TargetMachine> + </Link> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug/aa_demo.bsc</OutputFile> + </Bscmake> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\line_thickness.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/lion/Makefile b/examples/win32_api/lion/Makefile new file mode 100644 index 0000000..d7e4764 --- /dev/null +++ b/examples/win32_api/lion/Makefile @@ -0,0 +1,41 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=lion +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../parse_lion.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/lion/lion.dsp b/examples/win32_api/lion/lion.dsp new file mode 100644 index 0000000..91e658f --- /dev/null +++ b/examples/win32_api/lion/lion.dsp @@ -0,0 +1,143 @@ +# Microsoft Developer Studio Project File - Name="lion" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=lion - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "lion.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "lion.mak" CFG="lion - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "lion - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "lion - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "lion - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./lion.exe" + +!ELSEIF "$(CFG)" == "lion - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "lion - Win32 Release" +# Name "lion - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\lion.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\parse_lion.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_pixfmt_rgba.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/lion/lion.dsw b/examples/win32_api/lion/lion.dsw new file mode 100644 index 0000000..419081a --- /dev/null +++ b/examples/win32_api/lion/lion.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "lion"=.\lion.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/lion/lion.vcxproj b/examples/win32_api/lion/lion.vcxproj new file mode 100644 index 0000000..d0a6b81 --- /dev/null +++ b/examples/win32_api/lion/lion.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{636E09D4-0678-A349-3C54-B4F5D29D2440}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\lion.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\lion.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\lion.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\lion.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\lion.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\lion.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\lion.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\lion.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\lion.cpp" /> + <ClCompile Include="..\..\parse_lion.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_pixfmt_rgba.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/lion_lens/Makefile b/examples/win32_api/lion_lens/Makefile new file mode 100644 index 0000000..4403185 --- /dev/null +++ b/examples/win32_api/lion_lens/Makefile @@ -0,0 +1,41 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=lion_lens +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../parse_lion.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/lion_lens/lion_lens.dsp b/examples/win32_api/lion_lens/lion_lens.dsp new file mode 100644 index 0000000..82f0c43 --- /dev/null +++ b/examples/win32_api/lion_lens/lion_lens.dsp @@ -0,0 +1,147 @@ +# Microsoft Developer Studio Project File - Name="lion_lens" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=lion_lens - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "lion_lens.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "lion_lens.mak" CFG="lion_lens - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "lion_lens - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "lion_lens - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "lion_lens - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./lion_lens.exe" + +!ELSEIF "$(CFG)" == "lion_lens - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "lion_lens - Win32 Release" +# Name "lion_lens - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_warp_magnifier.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vpgen_segmentator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\lion_lens.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\parse_lion.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/lion_lens/lion_lens.dsw b/examples/win32_api/lion_lens/lion_lens.dsw new file mode 100644 index 0000000..57293ed --- /dev/null +++ b/examples/win32_api/lion_lens/lion_lens.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "lion_lens"=.\lion_lens.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/lion_lens/lion_lens.vcxproj b/examples/win32_api/lion_lens/lion_lens.vcxproj new file mode 100644 index 0000000..61e01ac --- /dev/null +++ b/examples/win32_api/lion_lens/lion_lens.vcxproj @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{F61620DA-B261-3836-F808-29991B8EB622}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\lion_lens.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\lion_lens.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\lion_lens.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\lion_lens.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\lion_lens.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\lion_lens.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\lion_lens.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\lion_lens.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_warp_magnifier.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\agg_vpgen_segmentator.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\lion_lens.cpp" /> + <ClCompile Include="..\..\parse_lion.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/lion_outline/Makefile b/examples/win32_api/lion_outline/Makefile new file mode 100644 index 0000000..b300ffc --- /dev/null +++ b/examples/win32_api/lion_outline/Makefile @@ -0,0 +1,41 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=lion_outline +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../parse_lion.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/lion_outline/lion_outline.dsp b/examples/win32_api/lion_outline/lion_outline.dsp new file mode 100644 index 0000000..5969ab0 --- /dev/null +++ b/examples/win32_api/lion_outline/lion_outline.dsp @@ -0,0 +1,155 @@ +# Microsoft Developer Studio Project File - Name="lion_outline" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=lion_outline - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "lion_outline.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "lion_outline.mak" CFG="lion_outline - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "lion_outline - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "lion_outline - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "lion_outline - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./lion_outline.exe" + +!ELSEIF "$(CFG)" == "lion_outline - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "lion_outline - Win32 Release" +# Name "lion_outline - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_aa_basics.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_profile_aa.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\lion_outline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\parse_lion.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/lion_outline/lion_outline.dsw b/examples/win32_api/lion_outline/lion_outline.dsw new file mode 100644 index 0000000..4a2871d --- /dev/null +++ b/examples/win32_api/lion_outline/lion_outline.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "lion_outline"=.\lion_outline.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/lion_outline/lion_outline.vcxproj b/examples/win32_api/lion_outline/lion_outline.vcxproj new file mode 100644 index 0000000..14bf079 --- /dev/null +++ b/examples/win32_api/lion_outline/lion_outline.vcxproj @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{1C282CA7-6080-A229-B4BD-22BFC1E56A0D}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\lion_outline.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\lion_outline.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\lion_outline.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\lion_outline.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\lion_outline.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\lion_outline.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\lion_outline.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\lion_outline.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_aa_basics.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_profile_aa.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\lion_outline.cpp" /> + <ClCompile Include="..\..\parse_lion.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/mol_view/Makefile b/examples/win32_api/mol_view/Makefile new file mode 100644 index 0000000..7cc5e0c --- /dev/null +++ b/examples/win32_api/mol_view/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=mol_view +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/mol_view/mol_view.dsp b/examples/win32_api/mol_view/mol_view.dsp new file mode 100644 index 0000000..16e20b8 --- /dev/null +++ b/examples/win32_api/mol_view/mol_view.dsp @@ -0,0 +1,177 @@ +# Microsoft Developer Studio Project File - Name="mol_view" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=mol_view - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mol_view.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mol_view.mak" CFG="mol_view - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mol_view - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "mol_view - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mol_view - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./mol_view.exe" + +!ELSEIF "$(CFG)" == "mol_view - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "mol_view - Win32 Release" +# Name "mol_view - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\mol_view.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_gsv_text.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_gsv_text_outline.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_math.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_path_storage.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\platform\agg_platform_support.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_rasterizer_scanline_aa.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_renderer_u8.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\ctrl\agg_scale_ctrl.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_trans_affine.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/mol_view/mol_view.dsw b/examples/win32_api/mol_view/mol_view.dsw new file mode 100644 index 0000000..2548625 --- /dev/null +++ b/examples/win32_api/mol_view/mol_view.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "mol_view"=.\mol_view.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/mol_view/mol_view.vcxproj b/examples/win32_api/mol_view/mol_view.vcxproj new file mode 100644 index 0000000..0ecce53 --- /dev/null +++ b/examples/win32_api/mol_view/mol_view.vcxproj @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{DA6B065B-8BD3-ADCD-28D7-D4BB41003200}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\mol_view.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\mol_view.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\mol_view.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\mol_view.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\mol_view.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\mol_view.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\mol_view.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\mol_view.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\mol_view.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_gsv_text.h" /> + <ClInclude Include="..\..\..\include\agg_gsv_text_outline.h" /> + <ClInclude Include="..\..\..\include\agg_math.h" /> + <ClInclude Include="..\..\..\include\agg_path_storage.h" /> + <ClInclude Include="..\..\..\include\platform\agg_platform_support.h" /> + <ClInclude Include="..\..\..\include\agg_rasterizer_scanline_aa.h" /> + <ClInclude Include="..\..\..\include\agg_renderer_u8.h" /> + <ClInclude Include="..\..\..\include\ctrl\agg_scale_ctrl.h" /> + <ClInclude Include="..\..\..\include\agg_trans_affine.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/mol_view/readme b/examples/win32_api/mol_view/readme new file mode 100644 index 0000000..0c52e2a --- /dev/null +++ b/examples/win32_api/mol_view/readme @@ -0,0 +1,2 @@ +Copy 1.sdf from ..\..\art before running this example. +Press PageUp/PgDown to switch between different molecules. diff --git a/examples/win32_api/multi_clip/Makefile b/examples/win32_api/multi_clip/Makefile new file mode 100644 index 0000000..a952736 --- /dev/null +++ b/examples/win32_api/multi_clip/Makefile @@ -0,0 +1,41 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=multi_clip +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../parse_lion.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/multi_clip/multi_clip.dsp b/examples/win32_api/multi_clip/multi_clip.dsp new file mode 100644 index 0000000..7e0d1ce --- /dev/null +++ b/examples/win32_api/multi_clip/multi_clip.dsp @@ -0,0 +1,151 @@ +# Microsoft Developer Studio Project File - Name="multi_clip" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=multi_clip - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "multi_clip.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "multi_clip.mak" CFG="multi_clip - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "multi_clip - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "multi_clip - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "multi_clip - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./multi_clip.exe" + +!ELSEIF "$(CFG)" == "multi_clip - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "multi_clip - Win32 Release" +# Name "multi_clip - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_aa_basics.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_profile_aa.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\multi_clip.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\parse_lion.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/multi_clip/multi_clip.dsw b/examples/win32_api/multi_clip/multi_clip.dsw new file mode 100644 index 0000000..20c3092 --- /dev/null +++ b/examples/win32_api/multi_clip/multi_clip.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "multi_clip"=.\multi_clip.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/multi_clip/multi_clip.vcxproj b/examples/win32_api/multi_clip/multi_clip.vcxproj new file mode 100644 index 0000000..ac282f4 --- /dev/null +++ b/examples/win32_api/multi_clip/multi_clip.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{7784A618-B98E-55A1-EB91-92B1BACE7C30}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\multi_clip.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\multi_clip.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\multi_clip.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\multi_clip.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\multi_clip.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\multi_clip.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\multi_clip.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\multi_clip.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_aa_basics.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_profile_aa.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\multi_clip.cpp" /> + <ClCompile Include="..\..\parse_lion.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/pattern_fill/Makefile b/examples/win32_api/pattern_fill/Makefile new file mode 100644 index 0000000..1514cbd --- /dev/null +++ b/examples/win32_api/pattern_fill/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=pattern_fill +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/pattern_fill/pattern_fill.dsp b/examples/win32_api/pattern_fill/pattern_fill.dsp new file mode 100644 index 0000000..002b235 --- /dev/null +++ b/examples/win32_api/pattern_fill/pattern_fill.dsp @@ -0,0 +1,169 @@ +# Microsoft Developer Studio Project File - Name="pattern_fill" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=pattern_fill - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pattern_fill.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pattern_fill.mak" CFG="pattern_fill - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pattern_fill - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "pattern_fill - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pattern_fill - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./pattern_fill.exe" +# SUBTRACT LINK32 /profile + +!ELSEIF "$(CFG)" == "pattern_fill - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "pattern_fill - Win32 Release" +# Name "pattern_fill - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_spline_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_smooth_poly1.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\pattern_fill.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_span_pattern_gray.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/pattern_fill/pattern_fill.dsw b/examples/win32_api/pattern_fill/pattern_fill.dsw new file mode 100644 index 0000000..40c7080 --- /dev/null +++ b/examples/win32_api/pattern_fill/pattern_fill.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "pattern_fill"=.\pattern_fill.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/pattern_fill/pattern_fill.vcxproj b/examples/win32_api/pattern_fill/pattern_fill.vcxproj new file mode 100644 index 0000000..e9d83d4 --- /dev/null +++ b/examples/win32_api/pattern_fill/pattern_fill.vcxproj @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4F89FFD1-37D2-CA3F-E88E-921B95C75FD8}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\pattern_fill.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\pattern_fill.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\pattern_fill.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\pattern_fill.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\pattern_fill.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\pattern_fill.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\pattern_fill.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\pattern_fill.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_spline_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_smooth_poly1.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\pattern_fill.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_span_pattern_gray.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/pattern_perspective/pattern_perspective.dsp b/examples/win32_api/pattern_perspective/pattern_perspective.dsp new file mode 100644 index 0000000..a2bf38b --- /dev/null +++ b/examples/win32_api/pattern_perspective/pattern_perspective.dsp @@ -0,0 +1,171 @@ +# Microsoft Developer Studio Project File - Name="pattern_perspective" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=pattern_perspective - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pattern_perspective.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pattern_perspective.mak" CFG="pattern_perspective - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pattern_perspective - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "pattern_perspective - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pattern_perspective - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./pattern_perspective.exe" + +!ELSEIF "$(CFG)" == "pattern_perspective - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "pattern_perspective - Win32 Release" +# Name "pattern_perspective - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\interactive_polygon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\pattern_perspective.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_span_allocator.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_generator.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_rgba.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_pattern_filter_gray.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_pattern_filter_rgb.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_pattern_filter_rgba.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/pattern_perspective/pattern_perspective.dsw b/examples/win32_api/pattern_perspective/pattern_perspective.dsw new file mode 100644 index 0000000..3e9efcb --- /dev/null +++ b/examples/win32_api/pattern_perspective/pattern_perspective.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "pattern_perspective"=.\pattern_perspective.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/pattern_perspective/pattern_perspective.vcxproj b/examples/win32_api/pattern_perspective/pattern_perspective.vcxproj new file mode 100644 index 0000000..a7b3850 --- /dev/null +++ b/examples/win32_api/pattern_perspective/pattern_perspective.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{48F212BB-AAEA-A634-2A87-90A48D73486E}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\pattern_perspective.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\pattern_perspective.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\pattern_perspective.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\pattern_perspective.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\pattern_perspective.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\pattern_perspective.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\pattern_perspective.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\pattern_perspective.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\interactive_polygon.cpp" /> + <ClCompile Include="..\..\pattern_perspective.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_span_allocator.h" /> + <ClInclude Include="..\..\..\include\agg_span_generator.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter_rgba.h" /> + <ClInclude Include="..\..\..\include\agg_span_pattern_filter_gray.h" /> + <ClInclude Include="..\..\..\include\agg_span_pattern_filter_rgb.h" /> + <ClInclude Include="..\..\..\include\agg_span_pattern_filter_rgba.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/pattern_resample/Makefile b/examples/win32_api/pattern_resample/Makefile new file mode 100644 index 0000000..5872723 --- /dev/null +++ b/examples/win32_api/pattern_resample/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=pattern_resample +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../interactive_polygon.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../interactive_polygon.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/pattern_resample/pattern_resample.dsp b/examples/win32_api/pattern_resample/pattern_resample.dsp new file mode 100644 index 0000000..79fb650 --- /dev/null +++ b/examples/win32_api/pattern_resample/pattern_resample.dsp @@ -0,0 +1,179 @@ +# Microsoft Developer Studio Project File - Name="pattern_resample" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=pattern_resample - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pattern_resample.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pattern_resample.mak" CFG="pattern_resample - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pattern_resample - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "pattern_resample - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pattern_resample - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./pattern_resample.exe" + +!ELSEIF "$(CFG)" == "pattern_resample - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "pattern_resample - Win32 Release" +# Name "pattern_resample - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_bezier_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_image_filters.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_polygon_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\interactive_polygon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\pattern_resample.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_color_gray.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_gray.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_image_filter_rgb.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_interpolator_persp.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_subdiv_adaptor.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/pattern_resample/pattern_resample.dsw b/examples/win32_api/pattern_resample/pattern_resample.dsw new file mode 100644 index 0000000..4f1b00d --- /dev/null +++ b/examples/win32_api/pattern_resample/pattern_resample.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "pattern_resample"=.\pattern_resample.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/pattern_resample/pattern_resample.vcxproj b/examples/win32_api/pattern_resample/pattern_resample.vcxproj new file mode 100644 index 0000000..84bbf67 --- /dev/null +++ b/examples/win32_api/pattern_resample/pattern_resample.vcxproj @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A113E8F7-2509-229F-D3D1-5ACFB8F27DF0}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\pattern_resample.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\pattern_resample.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\pattern_resample.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\pattern_resample.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\pattern_resample.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\pattern_resample.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\pattern_resample.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\pattern_resample.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_bezier_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_image_filters.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_polygon_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\interactive_polygon.cpp" /> + <ClCompile Include="..\..\pattern_resample.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_color_gray.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter_gray.h" /> + <ClInclude Include="..\..\..\include\agg_span_image_filter_rgb.h" /> + <ClInclude Include="..\..\..\include\agg_span_interpolator_persp.h" /> + <ClInclude Include="..\..\..\include\agg_span_subdiv_adaptor.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/perspective/Makefile b/examples/win32_api/perspective/Makefile new file mode 100644 index 0000000..2906f55 --- /dev/null +++ b/examples/win32_api/perspective/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=perspective +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../parse_lion.cpp \ +../../interactive_polygon.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/perspective/perspective.dsp b/examples/win32_api/perspective/perspective.dsp new file mode 100644 index 0000000..0b25b90 --- /dev/null +++ b/examples/win32_api/perspective/perspective.dsp @@ -0,0 +1,143 @@ +# Microsoft Developer Studio Project File - Name="perspective" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=perspective - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "perspective.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "perspective.mak" CFG="perspective - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "perspective - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "perspective - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "perspective - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./perspective.exe" + +!ELSEIF "$(CFG)" == "perspective - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "perspective - Win32 Release" +# Name "perspective - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\interactive_polygon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\parse_lion.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\perspective.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/perspective/perspective.dsw b/examples/win32_api/perspective/perspective.dsw new file mode 100644 index 0000000..61c2170 --- /dev/null +++ b/examples/win32_api/perspective/perspective.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "perspective"=.\perspective.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/perspective/perspective.vcxproj b/examples/win32_api/perspective/perspective.vcxproj new file mode 100644 index 0000000..75371c3 --- /dev/null +++ b/examples/win32_api/perspective/perspective.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{9E72EC9B-93D8-D749-88D7-25742B73A303}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\perspective.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\perspective.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\perspective.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\perspective.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\perspective.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\perspective.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\perspective.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\perspective.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\interactive_polygon.cpp" /> + <ClCompile Include="..\..\parse_lion.cpp" /> + <ClCompile Include="..\..\perspective.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/polymorphic_renderer/Makefile b/examples/win32_api/polymorphic_renderer/Makefile new file mode 100644 index 0000000..90aec09 --- /dev/null +++ b/examples/win32_api/polymorphic_renderer/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=polymorphic_renderer +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/polymorphic_renderer/polymorphic_renderer.dsp b/examples/win32_api/polymorphic_renderer/polymorphic_renderer.dsp new file mode 100644 index 0000000..d09e926 --- /dev/null +++ b/examples/win32_api/polymorphic_renderer/polymorphic_renderer.dsp @@ -0,0 +1,131 @@ +# Microsoft Developer Studio Project File - Name="polymorphic_renderer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=polymorphic_renderer - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "polymorphic_renderer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "polymorphic_renderer.mak" CFG="polymorphic_renderer - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "polymorphic_renderer - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "polymorphic_renderer - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "polymorphic_renderer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./polymorphic_renderer.exe" + +!ELSEIF "$(CFG)" == "polymorphic_renderer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "polymorphic_renderer - Win32 Release" +# Name "polymorphic_renderer - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_dash.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\polymorphic_renderer.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/polymorphic_renderer/polymorphic_renderer.dsw b/examples/win32_api/polymorphic_renderer/polymorphic_renderer.dsw new file mode 100644 index 0000000..f15a8d4 --- /dev/null +++ b/examples/win32_api/polymorphic_renderer/polymorphic_renderer.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "polymorphic_renderer"=.\polymorphic_renderer.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/polymorphic_renderer/polymorphic_renderer.vcxproj b/examples/win32_api/polymorphic_renderer/polymorphic_renderer.vcxproj new file mode 100644 index 0000000..17e1c09 --- /dev/null +++ b/examples/win32_api/polymorphic_renderer/polymorphic_renderer.vcxproj @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{01580078-9E68-4ECA-9C68-334F1CF215C2}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\polymorphic_renderer.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\polymorphic_renderer.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\polymorphic_renderer.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\polymorphic_renderer.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\polymorphic_renderer.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\polymorphic_renderer.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\polymorphic_renderer.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\polymorphic_renderer.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_dash.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\polymorphic_renderer.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/pure_api/StdAfx.cpp b/examples/win32_api/pure_api/StdAfx.cpp new file mode 100644 index 0000000..43fe99a --- /dev/null +++ b/examples/win32_api/pure_api/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// pure_api.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/examples/win32_api/pure_api/StdAfx.h b/examples/win32_api/pure_api/StdAfx.h new file mode 100644 index 0000000..75bd6b6 --- /dev/null +++ b/examples/win32_api/pure_api/StdAfx.h @@ -0,0 +1,32 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) +#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + + +// Windows Header Files: +#include <windows.h> + +// C RunTime Header Files +#include <stdlib.h> +#include <malloc.h> +#include <memory.h> +#include <tchar.h> + +// Local Header Files + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) diff --git a/examples/win32_api/pure_api/pure_api.cpp b/examples/win32_api/pure_api/pure_api.cpp new file mode 100644 index 0000000..79f21ea --- /dev/null +++ b/examples/win32_api/pure_api/pure_api.cpp @@ -0,0 +1,292 @@ +// pure_api.cpp : Defines the entry point for the application. +// + +#include "stdafx.h" +#include "resource.h" + +#include "agg_scanline_p.h" +#include "agg_renderer_scanline.h" +#include "agg_pixfmt_rgba.h" +#include "agg_rasterizer_scanline_aa.h" + +#define MAX_LOADSTRING 100 + +// Global Variables: +HINSTANCE hInst; // current instance +TCHAR szTitle[MAX_LOADSTRING]; // The title bar text +TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text + +// Foward declarations of functions included in this code module: +ATOM MyRegisterClass(HINSTANCE hInstance); +BOOL InitInstance(HINSTANCE, int); +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); + +int APIENTRY WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) +{ + // TODO: Place code here. + MSG msg; + HACCEL hAccelTable; + + // Initialize global strings + LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); + LoadString(hInstance, IDC_PURE_API, szWindowClass, MAX_LOADSTRING); + MyRegisterClass(hInstance); + + // Perform application initialization: + if (!InitInstance (hInstance, nCmdShow)) + { + return FALSE; + } + + hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_PURE_API); + + // Main message loop: + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + return msg.wParam; +} + + + +// +// FUNCTION: MyRegisterClass() +// +// PURPOSE: Registers the window class. +// +// COMMENTS: +// +// This function and its usage is only necessary if you want this code +// to be compatible with Win32 systems prior to the 'RegisterClassEx' +// function that was added to Windows 95. It is important to call this function +// so that the application will get 'well formed' small icons associated +// with it. +// +ATOM MyRegisterClass(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = (WNDPROC)WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_PURE_API); + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = (LPCSTR)IDC_PURE_API; + wcex.lpszClassName = szWindowClass; + wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); + + return RegisterClassEx(&wcex); +} + +// +// FUNCTION: InitInstance(HANDLE, int) +// +// PURPOSE: Saves instance handle and creates main window +// +// COMMENTS: +// +// In this function, we save the instance handle in a global variable and +// create and display the main program window. +// +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) +{ + HWND hWnd; + + hInst = hInstance; // Store instance handle in our global variable + + hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); + + if (!hWnd) + { + return FALSE; + } + + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + return TRUE; +} + +// +// FUNCTION: WndProc(HWND, unsigned, WORD, LONG) +// +// PURPOSE: Processes messages for the main window. +// +// WM_COMMAND - process the application menu +// WM_PAINT - Paint the main window +// WM_DESTROY - post a quit message and return +// +// +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + PAINTSTRUCT ps; + HDC hdc; + TCHAR szHello[MAX_LOADSTRING]; + LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING); + + switch (message) + { + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + // Parse the menu selections: + switch (wmId) + { + case IDM_ABOUT: + DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); + break; + case IDM_EXIT: + DestroyWindow(hWnd); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + break; + case WM_PAINT: + { + hdc = BeginPaint(hWnd, &ps); + RECT rt; + GetClientRect(hWnd, &rt); + + int width = rt.right - rt.left; + int height = rt.bottom - rt.top; + + //============================================================ + //Creating compatible DC and a bitmap to render the image + BITMAPINFO bmp_info; + bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmp_info.bmiHeader.biWidth = width; + bmp_info.bmiHeader.biHeight = height; + bmp_info.bmiHeader.biPlanes = 1; + bmp_info.bmiHeader.biBitCount = 32; + bmp_info.bmiHeader.biCompression = BI_RGB; + bmp_info.bmiHeader.biSizeImage = 0; + bmp_info.bmiHeader.biXPelsPerMeter = 0; + bmp_info.bmiHeader.biYPelsPerMeter = 0; + bmp_info.bmiHeader.biClrUsed = 0; + bmp_info.bmiHeader.biClrImportant = 0; + + HDC mem_dc = ::CreateCompatibleDC(hdc); + + void* buf = 0; + + HBITMAP bmp = ::CreateDIBSection( + mem_dc, + &bmp_info, + DIB_RGB_COLORS, + &buf, + 0, + 0 + ); + + // Selecting the object before doing anything allows you + // to use AGG together with native Windows GDI. + HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp); + + + //============================================================ + // AGG lowest level code. + agg::rendering_buffer rbuf; + rbuf.attach((unsigned char*)buf, width, height, -width*4); // Use negative stride in order + // to keep Y-axis consistent with + // WinGDI, i.e., going down. + + // Pixel format and basic primitives renderer + agg::pixfmt_bgra32 pixf(rbuf); + agg::renderer_base<agg::pixfmt_bgra32> renb(pixf); + + renb.clear(agg::rgba8(255, 255, 255, 255)); + + // Scanline renderer for solid filling. + agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgra32> > ren(renb); + + // Rasterizer & scanline + agg::rasterizer_scanline_aa<> ras; + agg::scanline_p8 sl; + + // Polygon (triangle) + ras.move_to_d(20.7, 34.15); + ras.line_to_d(398.23, 123.43); + ras.line_to_d(165.45, 401.87); + + // Setting the attrribute (color) & Rendering + ren.color(agg::rgba8(80, 90, 60)); + agg::render_scanlines(ras, sl, ren); + //============================================================ + + + + //------------------------------------------------------------ + // Display the image. If the image is B-G-R-A (32-bits per pixel) + // one can use AlphaBlend instead of BitBlt. In case of AlphaBlend + // one also should clear the image with zero alpha, i.e. rgba8(0,0,0,0) + + ::BitBlt( + hdc, + rt.left, + rt.top, + width, + height, + mem_dc, + 0, + 0, + SRCCOPY + ); + + // Free resources + ::SelectObject(mem_dc, temp); + ::DeleteObject(bmp); + ::DeleteObject(mem_dc); + + EndPaint(hWnd, &ps); + } + break; + + + case WM_ERASEBKGND: // Don't forget to do nothing on Erase Background event :-) + break; + + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + +// Mesage handler for about box. +LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + return TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) + { + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + break; + } + return FALSE; +} diff --git a/examples/win32_api/pure_api/pure_api.dsp b/examples/win32_api/pure_api/pure_api.dsp new file mode 100644 index 0000000..15091f7 --- /dev/null +++ b/examples/win32_api/pure_api/pure_api.dsp @@ -0,0 +1,137 @@ +# Microsoft Developer Studio Project File - Name="pure_api" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=pure_api - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pure_api.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pure_api.mak" CFG="pure_api - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pure_api - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "pure_api - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "pure_api - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 + +!ELSEIF "$(CFG)" == "pure_api - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "pure_api - Win32 Release" +# Name "pure_api - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\pure_api.cpp +# End Source File +# Begin Source File + +SOURCE=.\pure_api.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\pure_api.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\pure_api.ico +# End Source File +# Begin Source File + +SOURCE=.\small.ico +# End Source File +# End Group +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/examples/win32_api/pure_api/pure_api.dsw b/examples/win32_api/pure_api/pure_api.dsw new file mode 100644 index 0000000..ac7cbf1 --- /dev/null +++ b/examples/win32_api/pure_api/pure_api.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "pure_api"=.\pure_api.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/pure_api/pure_api.h b/examples/win32_api/pure_api/pure_api.h new file mode 100644 index 0000000..fbd3810 --- /dev/null +++ b/examples/win32_api/pure_api/pure_api.h @@ -0,0 +1,12 @@ + +#if !defined(AFX_PURE_API_H__B17A1161_38FE_4F00_8284_B215A497C968__INCLUDED_) +#define AFX_PURE_API_H__B17A1161_38FE_4F00_8284_B215A497C968__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "resource.h" + + +#endif // !defined(AFX_PURE_API_H__B17A1161_38FE_4F00_8284_B215A497C968__INCLUDED_) diff --git a/examples/win32_api/pure_api/pure_api.ico b/examples/win32_api/pure_api/pure_api.ico new file mode 100644 index 0000000000000000000000000000000000000000..386883523bcc032db77b69b047cbc5c15ae3b7fe GIT binary patch literal 1078 zcmeH_K@!3s3`IZHwe$$AoF2oYaWszOk{jR)NR>_(PRDWOZ<G8GXgc9bPLo2IWw=k$ zl{n8WUz~I~NegQMyJ1deycF5Hk4TY9j4j}ySX4@hLaDDxF^2Kj5-$7VrCfZ@!g)^) z2c`N~o@EQ<I4EaY4)g1ItG~gv4xrrt_S<J^O>gV)&%Zp6VccBVa2?uQ&sh9LW;!?J w2dwKn!S@jnH5GJS10MR3&V{nkc?%F^XS#jrb=7ItXV>BJ*yg?&H~)SR4}%AClK=n! literal 0 HcmV?d00001 diff --git a/examples/win32_api/pure_api/pure_api.rc b/examples/win32_api/pure_api/pure_api.rc new file mode 100644 index 0000000..9a8a2b1 --- /dev/null +++ b/examples/win32_api/pure_api/pure_api.rc @@ -0,0 +1,135 @@ +//Microsoft Visual C++ generated resource script. +// + +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. + +IDI_PURE_API ICON DISCARDABLE "pure_api.ICO" +IDI_SMALL ICON DISCARDABLE "SMALL.ICO" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDC_PURE_API MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "E&xit", IDM_EXIT + END + POPUP "&Help" + BEGIN + MENUITEM "&About ...", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDC_PURE_API ACCELERATORS MOVEABLE PURE +BEGIN + "?", IDM_ABOUT, ASCII, ALT + "/", IDM_ABOUT, ASCII, ALT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG DISCARDABLE 22, 17, 230, 75 +STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "About" +FONT 8, "System" +BEGIN + ICON IDI_PURE_API,IDC_MYICON,14,9,16,16 + LTEXT "pure_api Version 1.0",IDC_STATIC,49,10,119,8,SS_NOPREFIX + LTEXT "Copyright (C) 2002",IDC_STATIC,49,20,119,8 + DEFPUSHBUTTON "OK",IDOK,195,6,30,11,WS_GROUP +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""resource.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDC_PURE_API "PURE_API" + IDS_APP_TITLE "pure_api" + IDS_HELLO "Hello World!" +END + +#endif +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/examples/win32_api/pure_api/pure_api.vcxproj b/examples/win32_api/pure_api/pure_api.vcxproj new file mode 100644 index 0000000..9a8b483 --- /dev/null +++ b/examples/win32_api/pure_api/pure_api.vcxproj @@ -0,0 +1,161 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B1879B0F-4ACA-B943-3474-E584D659362F}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\pure_api.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\pure_api.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\pure_api.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\pure_api.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\pure_api.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\pure_api.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\pure_api.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\pure_api.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="pure_api.cpp" /> + <ClCompile Include="StdAfx.cpp" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="pure_api.rc" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="pure_api.h" /> + <ClInclude Include="resource.h" /> + <ClInclude Include="StdAfx.h" /> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="pure_api.ico" /> + <CustomBuild Include="small.ico" /> + <CustomBuild Include="ReadMe.txt" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/pure_api/resource.h b/examples/win32_api/pure_api/resource.h new file mode 100644 index 0000000..4a6517e --- /dev/null +++ b/examples/win32_api/pure_api/resource.h @@ -0,0 +1,27 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by PURE_API.RC +// +#define IDR_MAINFRAME 128 +#define IDD_PURE_API_DIALOG 102 +#define IDD_ABOUTBOX 103 +#define IDS_APP_TITLE 103 +#define IDM_ABOUT 104 +#define IDM_EXIT 105 +#define IDS_HELLO 106 +#define IDI_PURE_API 107 +#define IDI_SMALL 108 +#define IDC_PURE_API 109 +#define IDC_MYICON 2 +#define IDC_STATIC -1 +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/examples/win32_api/pure_api/small.ico b/examples/win32_api/pure_api/small.ico new file mode 100644 index 0000000000000000000000000000000000000000..8f94d9aa8285725af1920f17fa4ba90a7dad97fc GIT binary patch literal 318 zcmbu1u@S&92m|H2^tei$GGj6tBe4N_?3C#ONWzj2Y0z^{b=^ZcTR}S)7&>4n7JrdT ujNG@ttiTl!1hqz0y#czdCNotgVrj}ml}kwpjQ><xKQTJ~h4;=r`=1~8qePSd literal 0 HcmV?d00001 diff --git a/examples/win32_api/raster_text/Makefile b/examples/win32_api/raster_text/Makefile new file mode 100644 index 0000000..e2c3ee4 --- /dev/null +++ b/examples/win32_api/raster_text/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=raster_text +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/raster_text/raster_text.dsp b/examples/win32_api/raster_text/raster_text.dsp new file mode 100644 index 0000000..c7aa0ba --- /dev/null +++ b/examples/win32_api/raster_text/raster_text.dsp @@ -0,0 +1,151 @@ +# Microsoft Developer Studio Project File - Name="raster_text" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=raster_text - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "raster_text.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "raster_text.mak" CFG="raster_text - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "raster_text - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "raster_text - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "raster_text - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./raster_text.exe" + +!ELSEIF "$(CFG)" == "raster_text - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "raster_text - Win32 Release" +# Name "raster_text - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_embedded_raster_fonts.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\raster_text.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_embedded_raster_fonts.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_glyph_raster_bin.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_renderer_raster_text.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_span_gradient.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/raster_text/raster_text.dsw b/examples/win32_api/raster_text/raster_text.dsw new file mode 100644 index 0000000..8d7eb43 --- /dev/null +++ b/examples/win32_api/raster_text/raster_text.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "raster_text"=.\raster_text.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/raster_text/raster_text.vcxproj b/examples/win32_api/raster_text/raster_text.vcxproj new file mode 100644 index 0000000..734b7ee --- /dev/null +++ b/examples/win32_api/raster_text/raster_text.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EBCB363B-3793-507F-559E-30FF760ACB03}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\raster_text.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\raster_text.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\raster_text.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\raster_text.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\raster_text.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\raster_text.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\raster_text.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\raster_text.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_embedded_raster_fonts.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\raster_text.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_embedded_raster_fonts.h" /> + <ClInclude Include="..\..\..\include\agg_glyph_raster_bin.h" /> + <ClInclude Include="..\..\..\include\agg_renderer_raster_text.h" /> + <ClInclude Include="..\..\..\include\agg_span_gradient.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/rasterizer_compound/Makefile b/examples/win32_api/rasterizer_compound/Makefile new file mode 100644 index 0000000..61b5921 --- /dev/null +++ b/examples/win32_api/rasterizer_compound/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=rasterizer_compound +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/rasterizer_compound/rasterizer_compound.dsp b/examples/win32_api/rasterizer_compound/rasterizer_compound.dsp new file mode 100644 index 0000000..aa53347 --- /dev/null +++ b/examples/win32_api/rasterizer_compound/rasterizer_compound.dsp @@ -0,0 +1,159 @@ +# Microsoft Developer Studio Project File - Name="rasterizer_compound" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=rasterizer_compound - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rasterizer_compound.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rasterizer_compound.mak" CFG="rasterizer_compound - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rasterizer_compound - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "rasterizer_compound - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rasterizer_compound - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./rasterizer_compound.exe" + +!ELSEIF "$(CFG)" == "rasterizer_compound - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "rasterizer_compound - Win32 Release" +# Name "rasterizer_compound - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_arrowhead.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\rasterizer_compound.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/rasterizer_compound/rasterizer_compound.dsw b/examples/win32_api/rasterizer_compound/rasterizer_compound.dsw new file mode 100644 index 0000000..66e7432 --- /dev/null +++ b/examples/win32_api/rasterizer_compound/rasterizer_compound.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "rasterizer_compound"=.\rasterizer_compound.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/rasterizer_compound/rasterizer_compound.vcxproj b/examples/win32_api/rasterizer_compound/rasterizer_compound.vcxproj new file mode 100644 index 0000000..352b6f0 --- /dev/null +++ b/examples/win32_api/rasterizer_compound/rasterizer_compound.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CEA11124-03C2-06D5-39DC-9E9866B05B99}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\rasterizer_compound.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\rasterizer_compound.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\rasterizer_compound.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\rasterizer_compound.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\rasterizer_compound.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\rasterizer_compound.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\rasterizer_compound.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\rasterizer_compound.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_arrowhead.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\rasterizer_compound.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/rasterizers/Makefile b/examples/win32_api/rasterizers/Makefile new file mode 100644 index 0000000..2fc459f --- /dev/null +++ b/examples/win32_api/rasterizers/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=rasterizers +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/rasterizers/rasterizers.dsp b/examples/win32_api/rasterizers/rasterizers.dsp new file mode 100644 index 0000000..41fa5fd --- /dev/null +++ b/examples/win32_api/rasterizers/rasterizers.dsp @@ -0,0 +1,151 @@ +# Microsoft Developer Studio Project File - Name="rasterizers" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=rasterizers - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rasterizers.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rasterizers.mak" CFG="rasterizers - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rasterizers - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "rasterizers - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rasterizers - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./rasterizers.exe" + +!ELSEIF "$(CFG)" == "rasterizers - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "rasterizers - Win32 Release" +# Name "rasterizers - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_arrowhead.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_markers_term.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\rasterizers.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/rasterizers/rasterizers.dsw b/examples/win32_api/rasterizers/rasterizers.dsw new file mode 100644 index 0000000..6722fbf --- /dev/null +++ b/examples/win32_api/rasterizers/rasterizers.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "rasterizers"=.\rasterizers.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/rasterizers/rasterizers.vcxproj b/examples/win32_api/rasterizers/rasterizers.vcxproj new file mode 100644 index 0000000..0036f66 --- /dev/null +++ b/examples/win32_api/rasterizers/rasterizers.vcxproj @@ -0,0 +1,158 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D769103B-E6C3-D7A1-DF89-2ED1F326B9E5}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\rasterizers.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\rasterizers.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\rasterizers.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\rasterizers.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\rasterizers.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\rasterizers.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\rasterizers.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\rasterizers.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_arrowhead.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_markers_term.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\rasterizers.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/rasterizers2/Makefile b/examples/win32_api/rasterizers2/Makefile new file mode 100644 index 0000000..5cd8940 --- /dev/null +++ b/examples/win32_api/rasterizers2/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=rasterizers2 +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/rasterizers2/rasterizers2.dsp b/examples/win32_api/rasterizers2/rasterizers2.dsp new file mode 100644 index 0000000..a9e5b27 --- /dev/null +++ b/examples/win32_api/rasterizers2/rasterizers2.dsp @@ -0,0 +1,199 @@ +# Microsoft Developer Studio Project File - Name="rasterizers2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=rasterizers2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rasterizers2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rasterizers2.mak" CFG="rasterizers2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rasterizers2 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "rasterizers2 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rasterizers2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./rasterizers2.exe" + +!ELSEIF "$(CFG)" == "rasterizers2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "rasterizers2 - Win32 Release" +# Name "rasterizers2 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_arrowhead.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_aa_basics.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_profile_aa.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_rounded_rect.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_dash.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_markers_term.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_smooth_poly1.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\rasterizers2.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_line_aa_basics.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_renderer_markers.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_renderer_outline_aa.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\include\agg_renderer_outline_image.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/rasterizers2/rasterizers2.dsw b/examples/win32_api/rasterizers2/rasterizers2.dsw new file mode 100644 index 0000000..4b4dcce --- /dev/null +++ b/examples/win32_api/rasterizers2/rasterizers2.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "rasterizers2"=.\rasterizers2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/rasterizers2/rasterizers2.vcxproj b/examples/win32_api/rasterizers2/rasterizers2.vcxproj new file mode 100644 index 0000000..f1a8101 --- /dev/null +++ b/examples/win32_api/rasterizers2/rasterizers2.vcxproj @@ -0,0 +1,172 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{62F9D117-6886-87C3-B719-D59791638994}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\rasterizers2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\rasterizers2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\rasterizers2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\rasterizers2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\rasterizers2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\rasterizers2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\rasterizers2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\rasterizers2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_arrowhead.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_aa_basics.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_profile_aa.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\agg_rounded_rect.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_dash.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_markers_term.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_smooth_poly1.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\rasterizers2.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_line_aa_basics.h" /> + <ClInclude Include="..\..\..\include\agg_renderer_markers.h" /> + <ClInclude Include="..\..\..\include\agg_renderer_outline_aa.h" /> + <ClInclude Include="..\..\..\include\agg_renderer_outline_image.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/rounded_rect/Makefile b/examples/win32_api/rounded_rect/Makefile new file mode 100644 index 0000000..c7366a0 --- /dev/null +++ b/examples/win32_api/rounded_rect/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=rounded_rect +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/rounded_rect/rounded_rect.dsp b/examples/win32_api/rounded_rect/rounded_rect.dsp new file mode 100644 index 0000000..f18f426 --- /dev/null +++ b/examples/win32_api/rounded_rect/rounded_rect.dsp @@ -0,0 +1,147 @@ +# Microsoft Developer Studio Project File - Name="rounded_rect" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=rounded_rect - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rounded_rect.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rounded_rect.mak" CFG="rounded_rect - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rounded_rect - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "rounded_rect - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rounded_rect - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./rounded_rect.exe" + +!ELSEIF "$(CFG)" == "rounded_rect - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "rounded_rect - Win32 Release" +# Name "rounded_rect - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_rounded_rect.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\rounded_rect.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/rounded_rect/rounded_rect.dsw b/examples/win32_api/rounded_rect/rounded_rect.dsw new file mode 100644 index 0000000..48ebace --- /dev/null +++ b/examples/win32_api/rounded_rect/rounded_rect.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "rounded_rect"=.\rounded_rect.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/rounded_rect/rounded_rect.vcxproj b/examples/win32_api/rounded_rect/rounded_rect.vcxproj new file mode 100644 index 0000000..cb6df14 --- /dev/null +++ b/examples/win32_api/rounded_rect/rounded_rect.vcxproj @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{3DDFB788-8751-3001-00EF-B3E42C09FFD1}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\rounded_rect.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\rounded_rect.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\rounded_rect.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\rounded_rect.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\rounded_rect.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\rounded_rect.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\rounded_rect.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\rounded_rect.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\agg_rounded_rect.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\rounded_rect.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/scanline_boolean/Makefile b/examples/win32_api/scanline_boolean/Makefile new file mode 100644 index 0000000..7ba60a7 --- /dev/null +++ b/examples/win32_api/scanline_boolean/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=scanline_boolean +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../interactive_polygon.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../interactive_polygon.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/scanline_boolean/scanline_boolean.dsp b/examples/win32_api/scanline_boolean/scanline_boolean.dsp new file mode 100644 index 0000000..68f5bd4 --- /dev/null +++ b/examples/win32_api/scanline_boolean/scanline_boolean.dsp @@ -0,0 +1,151 @@ +# Microsoft Developer Studio Project File - Name="scanline_boolean" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=scanline_boolean - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "scanline_boolean.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "scanline_boolean.mak" CFG="scanline_boolean - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "scanline_boolean - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "scanline_boolean - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "scanline_boolean - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./scanline_boolean.exe" + +!ELSEIF "$(CFG)" == "scanline_boolean - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "scanline_boolean - Win32 Release" +# Name "scanline_boolean - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\interactive_polygon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\scanline_boolean.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_config.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/scanline_boolean/scanline_boolean.dsw b/examples/win32_api/scanline_boolean/scanline_boolean.dsw new file mode 100644 index 0000000..81e2b1c --- /dev/null +++ b/examples/win32_api/scanline_boolean/scanline_boolean.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "scanline_boolean"=.\scanline_boolean.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/scanline_boolean/scanline_boolean.vcxproj b/examples/win32_api/scanline_boolean/scanline_boolean.vcxproj new file mode 100644 index 0000000..ae074c0 --- /dev/null +++ b/examples/win32_api/scanline_boolean/scanline_boolean.vcxproj @@ -0,0 +1,162 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{FAA982B0-05C2-6440-9EC2-C0032CE56B4F}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\scanline_boolean.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\scanline_boolean.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\scanline_boolean.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\scanline_boolean.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\scanline_boolean.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\scanline_boolean.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\scanline_boolean.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\scanline_boolean.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\interactive_polygon.cpp" /> + <ClCompile Include="..\..\scanline_boolean.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_config.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/scanline_boolean2/Makefile b/examples/win32_api/scanline_boolean2/Makefile new file mode 100644 index 0000000..b7b9f74 --- /dev/null +++ b/examples/win32_api/scanline_boolean2/Makefile @@ -0,0 +1,42 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=scanline_boolean2 +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../make_arrows.cpp \ +../../make_gb_poly.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../*.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/scanline_boolean2/scanline_boolean2.dsp b/examples/win32_api/scanline_boolean2/scanline_boolean2.dsp new file mode 100644 index 0000000..5c651f2 --- /dev/null +++ b/examples/win32_api/scanline_boolean2/scanline_boolean2.dsp @@ -0,0 +1,155 @@ +# Microsoft Developer Studio Project File - Name="scanline_boolean2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=scanline_boolean2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "scanline_boolean2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "scanline_boolean2.mak" CFG="scanline_boolean2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "scanline_boolean2 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "scanline_boolean2 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "scanline_boolean2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /I "../../../gpc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./scanline_boolean2.exe" + +!ELSEIF "$(CFG)" == "scanline_boolean2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../gpc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "scanline_boolean2 - Win32 Release" +# Name "scanline_boolean2 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\make_arrows.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\make_gb_poly.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\scanline_boolean2.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/scanline_boolean2/scanline_boolean2.dsw b/examples/win32_api/scanline_boolean2/scanline_boolean2.dsw new file mode 100644 index 0000000..fd81937 --- /dev/null +++ b/examples/win32_api/scanline_boolean2/scanline_boolean2.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "scanline_boolean2"=.\scanline_boolean2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/scanline_boolean2/scanline_boolean2.vcxproj b/examples/win32_api/scanline_boolean2/scanline_boolean2.vcxproj new file mode 100644 index 0000000..dc1e7e1 --- /dev/null +++ b/examples/win32_api/scanline_boolean2/scanline_boolean2.vcxproj @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{88AC3D30-0084-D856-77C4-AB749ED4FFAA}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;../../../gpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\scanline_boolean2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\scanline_boolean2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\scanline_boolean2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\scanline_boolean2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;../../../gpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\scanline_boolean2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\scanline_boolean2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\scanline_boolean2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\scanline_boolean2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\make_arrows.cpp" /> + <ClCompile Include="..\..\make_gb_poly.cpp" /> + <ClCompile Include="..\..\scanline_boolean2.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/simple_blur/Makefile b/examples/win32_api/simple_blur/Makefile new file mode 100644 index 0000000..4c0b34f --- /dev/null +++ b/examples/win32_api/simple_blur/Makefile @@ -0,0 +1,41 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=simple_blur +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../parse_lion.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/simple_blur/simple_blur.dsp b/examples/win32_api/simple_blur/simple_blur.dsp new file mode 100644 index 0000000..16337c9 --- /dev/null +++ b/examples/win32_api/simple_blur/simple_blur.dsp @@ -0,0 +1,151 @@ +# Microsoft Developer Studio Project File - Name="simple_blur" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=simple_blur - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "simple_blur.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "simple_blur.mak" CFG="simple_blur - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "simple_blur - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "simple_blur - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "simple_blur - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./simple_blur.exe" + +!ELSEIF "$(CFG)" == "simple_blur - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "simple_blur - Win32 Release" +# Name "simple_blur - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_aa_basics.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_line_profile_aa.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_sqrt_tables.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\parse_lion.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\simple_blur.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/simple_blur/simple_blur.dsw b/examples/win32_api/simple_blur/simple_blur.dsw new file mode 100644 index 0000000..2d089a7 --- /dev/null +++ b/examples/win32_api/simple_blur/simple_blur.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "simple_blur"=.\simple_blur.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/simple_blur/simple_blur.vcxproj b/examples/win32_api/simple_blur/simple_blur.vcxproj new file mode 100644 index 0000000..25374ca --- /dev/null +++ b/examples/win32_api/simple_blur/simple_blur.vcxproj @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{F2CDDE95-2042-51DD-50AF-8CB33C91A363}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\simple_blur.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\simple_blur.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\simple_blur.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\simple_blur.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\simple_blur.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\simple_blur.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\simple_blur.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\simple_blur.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_aa_basics.cpp" /> + <ClCompile Include="..\..\..\src\agg_line_profile_aa.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_sqrt_tables.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\parse_lion.cpp" /> + <ClCompile Include="..\..\simple_blur.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/svg_test/svg_test.dsp b/examples/win32_api/svg_test/svg_test.dsp new file mode 100644 index 0000000..2cecc51 --- /dev/null +++ b/examples/win32_api/svg_test/svg_test.dsp @@ -0,0 +1,172 @@ +# Microsoft Developer Studio Project File - Name="svg_test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=svg_test - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "svg_test.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "svg_test.mak" CFG="svg_test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "svg_test - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "svg_test - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=xicl6.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "svg_test - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /I "../../../../Expat/Source/lib" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libexpat.lib /nologo /subsystem:windows /profile /machine:I386 /out:"./svg_test.exe" /libpath:"../../../../Expat/libs" + +!ELSEIF "$(CFG)" == "svg_test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../../Expat/Source/lib" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libexpat.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /libpath:"../../../../Expat/libs" + +!ENDIF + +# Begin Target + +# Name "svg_test - Win32 Release" +# Name "svg_test - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\svg_viewer\agg_svg_parser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\svg_viewer\agg_svg_path_renderer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\svg_viewer\agg_svg_path_tokenizer.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\svg_viewer\svg_test.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\svg_viewer\agg_svg_exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\svg_viewer\agg_svg_parser.h +# End Source File +# Begin Source File + +SOURCE=..\..\svg_viewer\agg_svg_path_renderer.h +# End Source File +# Begin Source File + +SOURCE=..\..\svg_viewer\agg_svg_path_tokenizer.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/svg_test/svg_test.dsw b/examples/win32_api/svg_test/svg_test.dsw new file mode 100644 index 0000000..ba99842 --- /dev/null +++ b/examples/win32_api/svg_test/svg_test.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "svg_test"=.\svg_test.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/svg_test/svg_test.vcxproj b/examples/win32_api/svg_test/svg_test.vcxproj new file mode 100644 index 0000000..d4d384a --- /dev/null +++ b/examples/win32_api/svg_test/svg_test.vcxproj @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6C17F9E2-2BC5-CA8F-EC31-588FE2AB9A37}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;../../../../Expat/Source/lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\svg_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\svg_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\svg_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\svg_test.exe</OutputFile> + <AdditionalLibraryDirectories>../../../../Expat/libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;libexpat.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;../../../../Expat/Source/lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\svg_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\svg_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\svg_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\svg_test.exe</OutputFile> + <AdditionalLibraryDirectories>../../../../Expat/libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;libexpat.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\svg_viewer\agg_svg_parser.cpp" /> + <ClCompile Include="..\..\svg_viewer\agg_svg_path_renderer.cpp" /> + <ClCompile Include="..\..\svg_viewer\agg_svg_path_tokenizer.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\svg_viewer\svg_test.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\svg_viewer\agg_svg_exception.h" /> + <ClInclude Include="..\..\svg_viewer\agg_svg_parser.h" /> + <ClInclude Include="..\..\svg_viewer\agg_svg_path_renderer.h" /> + <ClInclude Include="..\..\svg_viewer\agg_svg_path_tokenizer.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/trans_curve1/Makefile b/examples/win32_api/trans_curve1/Makefile new file mode 100644 index 0000000..0ac7a5d --- /dev/null +++ b/examples/win32_api/trans_curve1/Makefile @@ -0,0 +1,46 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=trans_curve1 +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) \ +-I../../../include \ +-I../../../font_win32_tt \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../interactive_polygon.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp \ +../../../font_win32_tt/agg_font_win32_tt.cpp + + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../interactive_polygon.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/trans_curve1/trans_curve1.dsp b/examples/win32_api/trans_curve1/trans_curve1.dsp new file mode 100644 index 0000000..c88cd71 --- /dev/null +++ b/examples/win32_api/trans_curve1/trans_curve1.dsp @@ -0,0 +1,167 @@ +# Microsoft Developer Studio Project File - Name="trans_curve1" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=trans_curve1 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "trans_curve1.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "trans_curve1.mak" CFG="trans_curve1 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "trans_curve1 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "trans_curve1 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "trans_curve1 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /I "../../../font_win32_tt" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./trans_curve1.exe" + +!ELSEIF "$(CFG)" == "trans_curve1 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../font_win32_tt" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "trans_curve1 - Win32 Release" +# Name "trans_curve1 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\font_win32_tt\agg_font_win32_tt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_single_path.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vpgen_segmentator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\interactive_polygon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\trans_curve1.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/trans_curve1/trans_curve1.dsw b/examples/win32_api/trans_curve1/trans_curve1.dsw new file mode 100644 index 0000000..591c227 --- /dev/null +++ b/examples/win32_api/trans_curve1/trans_curve1.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "trans_curve1"=.\trans_curve1.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/trans_curve1/trans_curve1.vcxproj b/examples/win32_api/trans_curve1/trans_curve1.vcxproj new file mode 100644 index 0000000..e2967f2 --- /dev/null +++ b/examples/win32_api/trans_curve1/trans_curve1.vcxproj @@ -0,0 +1,164 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{04837E0B-4CCF-A526-E9EC-E78EA4640AEB}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;../../../font_win32_tt;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\trans_curve1.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\trans_curve1.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\trans_curve1.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\trans_curve1.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;../../../font_win32_tt;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\trans_curve1.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\trans_curve1.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\trans_curve1.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\trans_curve1.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\font_win32_tt\agg_font_win32_tt.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_single_path.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_bspline.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\agg_vpgen_segmentator.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\interactive_polygon.cpp" /> + <ClCompile Include="..\..\trans_curve1.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/trans_curve2/Makefile b/examples/win32_api/trans_curve2/Makefile new file mode 100644 index 0000000..2802514 --- /dev/null +++ b/examples/win32_api/trans_curve2/Makefile @@ -0,0 +1,46 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=trans_curve2 +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) \ +-I../../../include \ +-I../../../font_win32_tt \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../interactive_polygon.cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp \ +../../../font_win32_tt/agg_font_win32_tt.cpp + + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../interactive_polygon.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/trans_curve2/trans_curve2.dsp b/examples/win32_api/trans_curve2/trans_curve2.dsp new file mode 100644 index 0000000..fcf9e12 --- /dev/null +++ b/examples/win32_api/trans_curve2/trans_curve2.dsp @@ -0,0 +1,171 @@ +# Microsoft Developer Studio Project File - Name="trans_curve2" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=trans_curve2 - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "trans_curve2.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "trans_curve2.mak" CFG="trans_curve2 - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "trans_curve2 - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "trans_curve2 - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "trans_curve2 - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /I "../../../font_win32_tt" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./trans_curve2.exe" + +!ELSEIF "$(CFG)" == "trans_curve2 - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../font_win32_tt" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AGG_BMP_NO_ALPHA_BLEND" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "trans_curve2 - Win32 Release" +# Name "trans_curve2 - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\font_win32_tt\agg_font_win32_tt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_double_path.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_bspline.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vpgen_segmentator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\interactive_polygon.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\trans_curve2.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\..\include\agg_trans_double_path.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/trans_curve2/trans_curve2.dsw b/examples/win32_api/trans_curve2/trans_curve2.dsw new file mode 100644 index 0000000..5dc7128 --- /dev/null +++ b/examples/win32_api/trans_curve2/trans_curve2.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "trans_curve2"=.\trans_curve2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/trans_curve2/trans_curve2.vcxproj b/examples/win32_api/trans_curve2/trans_curve2.vcxproj new file mode 100644 index 0000000..904e9de --- /dev/null +++ b/examples/win32_api/trans_curve2/trans_curve2.vcxproj @@ -0,0 +1,167 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{ABE48445-AD58-FBBA-6693-E5B8701BC6CF}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;../../../font_win32_tt;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\trans_curve2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\trans_curve2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\trans_curve2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\trans_curve2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;../../../font_win32_tt;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;AGG_BMP_NO_ALPHA_BLEND;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\trans_curve2.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\trans_curve2.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0419</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\trans_curve2.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\trans_curve2.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_bspline.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\font_win32_tt\agg_font_win32_tt.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_double_path.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_bspline.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\agg_vpgen_segmentator.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\interactive_polygon.cpp" /> + <ClCompile Include="..\..\trans_curve2.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\include\agg_trans_double_path.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/trans_polar/Makefile b/examples/win32_api/trans_polar/Makefile new file mode 100644 index 0000000..d7ec2e8 --- /dev/null +++ b/examples/win32_api/trans_polar/Makefile @@ -0,0 +1,40 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=trans_polar +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) -I../../../include \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/trans_polar/trans_polar.dsp b/examples/win32_api/trans_polar/trans_polar.dsp new file mode 100644 index 0000000..74e31e7 --- /dev/null +++ b/examples/win32_api/trans_polar/trans_polar.dsp @@ -0,0 +1,143 @@ +# Microsoft Developer Studio Project File - Name="trans_polar" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=trans_polar - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "trans_polar.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "trans_polar.mak" CFG="trans_polar - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "trans_polar - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "trans_polar - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "trans_polar - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./trans_polar.exe" + +!ELSEIF "$(CFG)" == "trans_polar - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "trans_polar - Win32 Release" +# Name "trans_polar - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vpgen_segmentator.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\trans_polar.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/trans_polar/trans_polar.dsw b/examples/win32_api/trans_polar/trans_polar.dsw new file mode 100644 index 0000000..69f1569 --- /dev/null +++ b/examples/win32_api/trans_polar/trans_polar.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "trans_polar"=.\trans_polar.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/trans_polar/trans_polar.vcxproj b/examples/win32_api/trans_polar/trans_polar.vcxproj new file mode 100644 index 0000000..e00bc2a --- /dev/null +++ b/examples/win32_api/trans_polar/trans_polar.vcxproj @@ -0,0 +1,156 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{BF39ECC1-095F-E7FB-BBB6-563332B4470F}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\trans_polar.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\trans_polar.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\trans_polar.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\trans_polar.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\trans_polar.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\trans_polar.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\trans_polar.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\trans_polar.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\agg_vpgen_segmentator.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\trans_polar.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api/truetype_test/Makefile b/examples/win32_api/truetype_test/Makefile new file mode 100644 index 0000000..3158344 --- /dev/null +++ b/examples/win32_api/truetype_test/Makefile @@ -0,0 +1,45 @@ +# +# This makefile can be used to build a Win32 application under Cygwin +# + +include ../../../Makefile.in.$(shell uname) + +PROGNAME=truetype_test +OUTNAME=$(PROGNAME) +PLATFORM=win32 + +CXXFLAGS= $(AGGCXXFLAGS) \ +-I../../../include \ +-I../../../font_win32_tt \ +-I/usr/X11R6/include \ +-L/usr/X11R6/lib \ +-L../../../src \ +$(PIXFMT) + +LIBS = $(AGGLIBS) -lm -lgdi32 + +SRC=\ +../../$(PROGNAME).cpp \ +../../../src/platform/$(PLATFORM)/agg_platform_support.cpp \ +../../../src/platform/$(PLATFORM)/agg_win32_bmp.cpp \ +../../../font_win32_tt/agg_font_win32_tt.cpp + + +OBJ= $(SRC:.cpp=.o) + +$(OUTNAME): $(OBJ) + $(CXX) $(CXXFLAGS) $^ -o $(OUTNAME) $(LIBS) + +clean: + rm -f $(OUTNAME) + rm -f ../../$(PROGNAME).o + rm -f ../../interactive_polygon.o + rm -f ../../../src/platform/$(PLATFORM)/agg_platform_support.o + rm -f gamma.txt + rm -f gamma.bin + +%.o: %.cpp + @echo \< $*.cpp \> + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + + diff --git a/examples/win32_api/truetype_test/truetype_test.dsp b/examples/win32_api/truetype_test/truetype_test.dsp new file mode 100644 index 0000000..b3c468d --- /dev/null +++ b/examples/win32_api/truetype_test/truetype_test.dsp @@ -0,0 +1,155 @@ +# Microsoft Developer Studio Project File - Name="truetype_test" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=truetype_test - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "truetype_test.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "truetype_test.mak" CFG="truetype_test - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "truetype_test - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "truetype_test - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "truetype_test - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /I "../../../font_win32_tt" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"./truetype_test.exe" + +!ELSEIF "$(CFG)" == "truetype_test - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../font_win32_tt" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "truetype_test - Win32 Release" +# Name "truetype_test - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\agg_bezier_arc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_cbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_curves.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\font_win32_tt\agg_font_win32_tt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_gsv_text.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_platform_support.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_rbox_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\ctrl\agg_slider_ctrl.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_trans_affine.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_contour.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\agg_vcgen_stroke.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\platform\win32\agg_win32_bmp.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\truetype_test.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/examples/win32_api/truetype_test/truetype_test.dsw b/examples/win32_api/truetype_test/truetype_test.dsw new file mode 100644 index 0000000..4f35984 --- /dev/null +++ b/examples/win32_api/truetype_test/truetype_test.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "truetype_test"=.\truetype_test.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/examples/win32_api/truetype_test/truetype_test.vcxproj b/examples/win32_api/truetype_test/truetype_test.vcxproj new file mode 100644 index 0000000..c3542ab --- /dev/null +++ b/examples/win32_api/truetype_test/truetype_test.vcxproj @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Template|Win32"> + <Configuration>Template</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EA706565-3FDB-5B31-6C36-C27C2AD257EF}</ProjectGuid> + <SccProjectName /> + <SccLocalPath /> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> + <Import Project="..\agg.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>.\Debug\</OutDir> + <IntDir>.\Debug\</IntDir> + <LinkIncremental>true</LinkIncremental> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>.\Release\</OutDir> + <IntDir>.\Release\</IntDir> + <LinkIncremental>false</LinkIncremental> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <InlineFunctionExpansion>Default</InlineFunctionExpansion> + <FunctionLevelLinking>false</FunctionLevelLinking> + <Optimization>Disabled</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <MinimalRebuild>true</MinimalRebuild> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <AdditionalIncludeDirectories>../../../include;../../../font_win32_tt;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Debug\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Debug\truetype_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Debug\</ObjectFileName> + <ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Debug\truetype_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Debug\truetype_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <GenerateDebugInformation>true</GenerateDebugInformation> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Debug\truetype_test.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <StringPooling>true</StringPooling> + <FunctionLevelLinking>true</FunctionLevelLinking> + <Optimization>MaxSpeed</Optimization> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WarningLevel>Level3</WarningLevel> + <AdditionalIncludeDirectories>../../../include;../../../font_win32_tt;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AssemblerListingLocation>.\Release\</AssemblerListingLocation> + <PrecompiledHeaderOutputFile>.\Release\truetype_test.pch</PrecompiledHeaderOutputFile> + <ObjectFileName>.\Release\</ObjectFileName> + <ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName> + </ClCompile> + <Midl> + <SuppressStartupBanner>true</SuppressStartupBanner> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <TypeLibraryName>.\Release\truetype_test.tlb</TypeLibraryName> + <MkTypLibCompatible>true</MkTypLibCompatible> + <TargetEnvironment>Win32</TargetEnvironment> + </Midl> + <ResourceCompile> + <Culture>0x0409</Culture> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Bscmake> + <SuppressStartupBanner>true</SuppressStartupBanner> + <OutputFile>.\Release\truetype_test.bsc</OutputFile> + </Bscmake> + <Link> + <SuppressStartupBanner>true</SuppressStartupBanner> + <SubSystem>Windows</SubSystem> + <OutputFile>.\Release\truetype_test.exe</OutputFile> + <AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\src\agg_bezier_arc.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_cbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_curves.cpp" /> + <ClCompile Include="..\..\..\font_win32_tt\agg_font_win32_tt.cpp" /> + <ClCompile Include="..\..\..\src\agg_gsv_text.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_platform_support.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_rbox_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\ctrl\agg_slider_ctrl.cpp" /> + <ClCompile Include="..\..\..\src\agg_trans_affine.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_contour.cpp" /> + <ClCompile Include="..\..\..\src\agg_vcgen_stroke.cpp" /> + <ClCompile Include="..\..\..\src\platform\win32\agg_win32_bmp.cpp" /> + <ClCompile Include="..\..\truetype_test.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/examples/win32_api_dmc/Makefile b/examples/win32_api_dmc/Makefile new file mode 100644 index 0000000..b9cd218 --- /dev/null +++ b/examples/win32_api_dmc/Makefile @@ -0,0 +1,593 @@ +#============================================== +# Digital Mars Makefile +# +# Modify this variable if necessary +# +DM = \dm\bin +# + +CXX = $(DM)\dmc.exe -c -I..\..\include -I..\..\gpc -I..\..\font_win32_tt +C = $(DM)\dmc.exe -c -o+speed -I..\..\gpc +LINK = $(DM)\dmc.exe -L$(DM)\link.exe -L/SU:WINDOWS gdi32.lib +LIB = $(DM)\lib.exe + +all: aa_demo.exe \ + aa_test.exe \ + alpha_gradient.exe \ + alpha_mask.exe \ + alpha_mask2.exe \ + alpha_mask3.exe \ + bezier_div.exe \ + blur.exe \ + blend_color.exe \ + bspline.exe \ + circles.exe \ + component_rendering.exe \ + compositing.exe \ + compositing2.exe \ + conv_contour.exe \ + conv_dash_marker.exe \ + conv_stroke.exe \ + distortions.exe \ + flash_rasterizer.exe \ + flash_rasterizer2.exe \ + gamma_correction.exe \ + gamma_ctrl.exe \ + gamma_tuner.exe \ + gouraud.exe \ + gouraud_mesh.exe \ + gpc_test.exe \ + gradient_focal.exe \ + gradients.exe \ + graph_test.exe \ + idea.exe \ + image1.exe \ + image_alpha.exe \ + image_filters.exe \ + image_filters2.exe \ + image_fltr_graph.exe \ + image_perspective.exe \ + image_resample.exe \ + image_transforms.exe \ + line_patterns.exe \ + line_patterns_clip.exe \ + lion.exe \ + lion_lens.exe \ + lion_outline.exe \ + mol_view.exe \ + multi_clip.exe \ + pattern_fill.exe \ + pattern_perspective.exe \ + pattern_resample.exe \ + perspective.exe \ + polymorphic_renderer.exe \ + rasterizers.exe \ + rasterizers2.exe \ + rasterizer_compound.exe \ + raster_text.exe \ + rounded_rect.exe \ + scanline_boolean.exe \ + scanline_boolean2.exe \ + simple_blur.exe \ + trans_curve1.exe \ + trans_curve2.exe \ + trans_polar.exe \ + truetype_test.exe + +aa_demo.exe: aa_demo.obj agg.lib + $(LINK) $** + +aa_demo.obj: ..\aa_demo.cpp + $(CXX) $** -o$@ + +aa_test.exe: aa_test.obj agg.lib + $(LINK) $** + +aa_test.obj: ..\aa_test.cpp + $(CXX) $** -o$@ + +alpha_gradient.exe: alpha_gradient.obj agg.lib + $(LINK) $** + +alpha_gradient.obj: ..\alpha_gradient.cpp + $(CXX) $** -o$@ + +alpha_mask.exe: alpha_mask.obj parse_lion.obj agg.lib + $(LINK) $** + +alpha_mask.obj: ..\alpha_mask.cpp + $(CXX) $** -o$@ + +alpha_mask2.exe: alpha_mask2.obj parse_lion.obj agg.lib + $(LINK) $** + +alpha_mask2.obj: ..\alpha_mask2.cpp + $(CXX) $** -o$@ + +alpha_mask3.exe: alpha_mask3.obj make_arrows.obj make_gb_poly.obj agg.lib + $(LINK) $** + +alpha_mask3.obj: ..\alpha_mask3.cpp + $(CXX) $** -o$@ + +bezier_div.exe: bezier_div.obj agg.lib + $(LINK) $** + +bezier_div.obj: ..\bezier_div.cpp + $(CXX) $** -o$@ + +blur.exe: blur.obj agg.lib + $(LINK) $** + +blur.obj: ..\blur.cpp + $(CXX) $** -o$@ + +blend_color.exe: blend_color.obj agg.lib + $(LINK) $** + +blend_color.obj: ..\blend_color.cpp + $(CXX) $** -o$@ + +bspline.exe: bspline.obj interactive_polygon.obj agg.lib + $(LINK) $** + +bspline.obj: ..\bspline.cpp + $(CXX) $** -o$@ + +circles.exe: circles.obj agg.lib + $(LINK) $** + +circles.obj: ..\circles.cpp + $(CXX) $** -o$@ + +component_rendering.exe: component_rendering.obj agg.lib + $(LINK) $** + +component_rendering.obj: ..\component_rendering.cpp + $(CXX) $** -o$@ + +compositing.exe: compositing.obj agg.lib + $(LINK) $** + +compositing.obj: ..\compositing.cpp + $(CXX) $** -o$@ + +compositing2.exe: compositing2.obj agg.lib + $(LINK) $** + +compositing2.obj: ..\compositing2.cpp + $(CXX) $** -o$@ + +conv_contour.exe: conv_contour.obj agg.lib + $(LINK) $** + +conv_contour.obj: ..\conv_contour.cpp + $(CXX) $** -o$@ + +conv_dash_marker.exe: conv_dash_marker.obj agg.lib + $(LINK) $** + +conv_dash_marker.obj: ..\conv_dash_marker.cpp + $(CXX) $** -o$@ + +conv_stroke.exe: conv_stroke.obj agg.lib + $(LINK) $** + +conv_stroke.obj: ..\conv_stroke.cpp + $(CXX) $** -o$@ + +distortions.exe: distortions.obj agg.lib + $(LINK) $** + +distortions.obj: ..\distortions.cpp + $(CXX) $** -o$@ + +flash_rasterizer.exe: flash_rasterizer.obj agg.lib + $(LINK) $** + +flash_rasterizer.obj: ..\flash_rasterizer.cpp + $(CXX) $** -o$@ + +flash_rasterizer2.exe: flash_rasterizer2.obj agg.lib + $(LINK) $** + +flash_rasterizer2.obj: ..\flash_rasterizer2.cpp + $(CXX) $** -o$@ + +gamma_correction.exe: gamma_correction.obj agg.lib + $(LINK) $** + +gamma_correction.obj: ..\gamma_correction.cpp + $(CXX) $** -o$@ + +gamma_ctrl.exe: gamma_ctrl.obj agg.lib + $(LINK) $** + +gamma_ctrl.obj: ..\gamma_ctrl.cpp + $(CXX) $** -o$@ + +gamma_tuner.exe: gamma_tuner.obj agg.lib + $(LINK) $** + +gamma_tuner.obj: ..\gamma_tuner.cpp + $(CXX) $** -o$@ + +gouraud.exe: gouraud.obj agg.lib + $(LINK) $** + +gouraud.obj: ..\gouraud.cpp + $(CXX) $** -o$@ + +gouraud_mesh.exe: gouraud_mesh.obj agg.lib + $(LINK) $** + +gouraud_mesh.obj: ..\gouraud_mesh.cpp + $(CXX) $** -o$@ + +gpc_test.exe: gpc_test.obj make_arrows.obj make_gb_poly.obj agg.lib + $(LINK) $** + +gpc_test.obj: ..\gpc_test.cpp + $(CXX) $** -o$@ + +gradient_focal.exe: gradient_focal.obj agg.lib + $(LINK) $** + +gradient_focal.obj: ..\gradient_focal.cpp + $(CXX) $** -o$@ + +gradients.exe: gradients.obj agg.lib + $(LINK) $** + +gradients.obj: ..\gradients.cpp + $(CXX) $** -o$@ + +graph_test.exe: graph_test.obj agg.lib + $(LINK) $** + +graph_test.obj: ..\graph_test.cpp + $(CXX) $** -o$@ + +idea.exe: idea.obj agg.lib + $(LINK) $** + +idea.obj: ..\idea.cpp + $(CXX) $** -o$@ + +image1.exe: image1.obj agg.lib + $(LINK) $** + +image1.obj: ..\image1.cpp + $(CXX) $** -o$@ + +image_alpha.exe: image_alpha.obj agg.lib + $(LINK) $** + +image_alpha.obj: ..\image_alpha.cpp + $(CXX) $** -o$@ + +image_filters.exe: image_filters.obj agg.lib + $(LINK) $** + +image_filters.obj: ..\image_filters.cpp + $(CXX) $** -o$@ + +image_filters2.exe: image_filters2.obj agg.lib + $(LINK) $** + +image_filters2.obj: ..\image_filters2.cpp + $(CXX) $** -o$@ + +image_fltr_graph.exe: image_fltr_graph.obj agg.lib + $(LINK) $** + +image_fltr_graph.obj: ..\image_fltr_graph.cpp + $(CXX) $** -o$@ + +image_perspective.exe: image_perspective.obj interactive_polygon.obj agg.lib + $(LINK) $** + +image_perspective.obj: ..\image_perspective.cpp + $(CXX) $** -o$@ + +image_resample.exe: image_resample.obj interactive_polygon.obj agg.lib + $(LINK) $** + +image_resample.obj: ..\image_resample.cpp + $(CXX) $** -o$@ + +image_transforms.exe: image_transforms.obj agg.lib + $(LINK) $** + +image_transforms.obj: ..\image_transforms.cpp + $(CXX) $** -o$@ + +line_patterns.exe: line_patterns.obj agg.lib + $(LINK) $** + +line_patterns.obj: ..\line_patterns.cpp + $(CXX) $** -o$@ + +line_patterns_clip.exe: line_patterns_clip.obj agg.lib + $(LINK) $** + +line_patterns_clip.obj: ..\line_patterns_clip.cpp + $(CXX) $** -o$@ + +lion.exe: lion.obj parse_lion.obj agg.lib + $(LINK) $** + +lion.obj: ..\lion.cpp + $(CXX) $** -o$@ + +lion_lens.exe: lion_lens.obj parse_lion.obj agg.lib + $(LINK) $** + +lion_lens.obj: ..\lion_lens.cpp + $(CXX) $** -o$@ + +lion_outline.exe: lion_outline.obj parse_lion.obj agg.lib + $(LINK) $** + +lion_outline.obj: ..\lion_outline.cpp + $(CXX) $** -o$@ + +mol_view.exe: mol_view.obj agg.lib + $(LINK) $** + +mol_view.obj: ..\mol_view.cpp + $(CXX) $** -o$@ + +multi_clip.exe: multi_clip.obj parse_lion.obj agg.lib + $(LINK) $** + +multi_clip.obj: ..\multi_clip.cpp + $(CXX) $** -o$@ + +pattern_fill.exe: pattern_fill.obj agg.lib + $(LINK) $** + +pattern_fill.obj: ..\pattern_fill.cpp + $(CXX) $** -o$@ + +pattern_perspective.exe: pattern_perspective.obj interactive_polygon.obj agg.lib + $(LINK) $** + +pattern_perspective.obj: ..\pattern_perspective.cpp + $(CXX) $** -o$@ + +pattern_resample.exe: pattern_resample.obj interactive_polygon.obj agg.lib + $(LINK) $** + +pattern_resample.obj: ..\pattern_resample.cpp + $(CXX) $** -o$@ + +perspective.exe: perspective.obj parse_lion.obj interactive_polygon.obj agg.lib + $(LINK) $** + +perspective.obj: ..\perspective.cpp + $(CXX) $** -o$@ + +polymorphic_renderer.exe: polymorphic_renderer.obj agg.lib + $(LINK) $** + +polymorphic_renderer.obj: ..\polymorphic_renderer.cpp + $(CXX) $** -o$@ + +rasterizers.exe: rasterizers.obj agg.lib + $(LINK) $** + +rasterizers.obj: ..\rasterizers.cpp + $(CXX) $** -o$@ + +rasterizers2.exe: rasterizers2.obj agg.lib + $(LINK) $** + +rasterizers2.obj: ..\rasterizers2.cpp + $(CXX) $** -o$@ + +rasterizer_compound.exe: rasterizer_compound.obj agg.lib + $(LINK) $** + +rasterizer_compound.obj: ..\rasterizer_compound.cpp + $(CXX) $** -o$@ + +raster_text.exe: raster_text.obj agg.lib + $(LINK) $** + +raster_text.obj: ..\raster_text.cpp + $(CXX) $** -o$@ + +rounded_rect.exe: rounded_rect.obj agg.lib + $(LINK) $** + +rounded_rect.obj: ..\rounded_rect.cpp + $(CXX) $** -o$@ + +scanline_boolean.exe: scanline_boolean.obj interactive_polygon.obj agg.lib + $(LINK) $** + +scanline_boolean.obj: ..\scanline_boolean.cpp + $(CXX) $** -o$@ + +scanline_boolean2.exe: scanline_boolean2.obj make_arrows.obj make_gb_poly.obj agg.lib + $(LINK) $** + +scanline_boolean2.obj: ..\scanline_boolean2.cpp + $(CXX) $** -o$@ + +simple_blur.exe: simple_blur.obj parse_lion.obj agg.lib + $(LINK) $** + +simple_blur.obj: ..\simple_blur.cpp + $(CXX) $** -o$@ + +trans_curve1.exe: trans_curve1.obj interactive_polygon.obj agg.lib + $(LINK) $** + +trans_curve1.obj: ..\trans_curve1.cpp + $(CXX) $** -o$@ + +trans_curve2.exe: trans_curve2.obj interactive_polygon.obj agg.lib + $(LINK) $** + +trans_curve2.obj: ..\trans_curve2.cpp + $(CXX) $** -o$@ + +trans_polar.exe: trans_polar.obj agg.lib + $(LINK) $** + +trans_polar.obj: ..\trans_polar.cpp + $(CXX) $** -o$@ + +truetype_test.exe: truetype_test.obj agg.lib + $(LINK) $** + +truetype_test.obj: ..\truetype_test.cpp + $(CXX) $** -o$@ + +parse_lion.obj: ..\parse_lion.cpp + $(CXX) $** -o$@ + +make_arrows.obj: ..\make_arrows.cpp + $(CXX) $** -o$@ + +make_gb_poly.obj: ..\make_gb_poly.cpp + $(CXX) $** -o$@ + +interactive_polygon.obj: ..\interactive_polygon.cpp + $(CXX) $** -o$@ + +agg.lib: agg_arc.obj agg_arrowhead.obj agg_bezier_arc.obj agg_bspline.obj agg_curves.obj \ + agg_embedded_raster_fonts.obj agg_gsv_text.obj agg_image_filters.obj \ + agg_line_aa_basics.obj agg_line_profile_aa.obj agg_rounded_rect.obj \ + agg_sqrt_tables.obj agg_trans_affine.obj agg_trans_double_path.obj \ + agg_trans_single_path.obj agg_trans_warp_magnifier.obj agg_vcgen_bspline.obj \ + agg_vcgen_contour.obj agg_vcgen_dash.obj agg_vcgen_markers_term.obj \ + agg_vcgen_smooth_poly1.obj agg_vcgen_stroke.obj agg_vpgen_clip_polygon.obj \ + agg_vpgen_clip_polyline.obj agg_vpgen_segmentator.obj agg_font_win32_tt.obj \ + agg_bezier_ctrl.obj agg_cbox_ctrl.obj agg_gamma_ctrl.obj agg_gamma_spline.obj \ + agg_polygon_ctrl.obj agg_rbox_ctrl.obj agg_scale_ctrl.obj agg_slider_ctrl.obj \ + agg_spline_ctrl.obj agg_platform_support.obj agg_win32_bmp.obj gpc.obj + $(LIB) -c $@ $** + +agg_arc.obj: ..\..\src\agg_arc.cpp + $(CXX) $** -o$@ + +agg_arrowhead.obj: ..\..\src\agg_arrowhead.cpp + $(CXX) $** -o$@ + +agg_bezier_arc.obj: ..\..\src\agg_bezier_arc.cpp + $(CXX) $** -o$@ + +agg_bspline.obj: ..\..\src\agg_bspline.cpp + $(CXX) $** -o$@ + +agg_curves.obj: ..\..\src\agg_curves.cpp + $(CXX) $** -o$@ + +agg_embedded_raster_fonts.obj: ..\..\src\agg_embedded_raster_fonts.cpp + $(CXX) $** -o$@ + +agg_gsv_text.obj: ..\..\src\agg_gsv_text.cpp + $(CXX) $** -o$@ + +agg_image_filters.obj: ..\..\src\agg_image_filters.cpp + $(CXX) $** -o$@ + +agg_line_aa_basics.obj: ..\..\src\agg_line_aa_basics.cpp + $(CXX) $** -o$@ + +agg_line_profile_aa.obj: ..\..\src\agg_line_profile_aa.cpp + $(CXX) $** -o$@ + +agg_rounded_rect.obj: ..\..\src\agg_rounded_rect.cpp + $(CXX) $** -o$@ + +agg_sqrt_tables.obj: ..\..\src\agg_sqrt_tables.cpp + $(CXX) $** -o$@ + +agg_trans_affine.obj: ..\..\src\agg_trans_affine.cpp + $(CXX) $** -o$@ + +agg_trans_double_path.obj: ..\..\src\agg_trans_double_path.cpp + $(CXX) $** -o$@ + +agg_trans_single_path.obj: ..\..\src\agg_trans_single_path.cpp + $(CXX) $** -o$@ + +agg_trans_warp_magnifier.obj: ..\..\src\agg_trans_warp_magnifier.cpp + $(CXX) $** -o$@ + +agg_vcgen_bspline.obj: ..\..\src\agg_vcgen_bspline.cpp + $(CXX) $** -o$@ + +agg_vcgen_contour.obj: ..\..\src\agg_vcgen_contour.cpp + $(CXX) $** -o$@ + +agg_vcgen_dash.obj: ..\..\src\agg_vcgen_dash.cpp + $(CXX) $** -o$@ + +agg_vcgen_markers_term.obj: ..\..\src\agg_vcgen_markers_term.cpp + $(CXX) $** -o$@ + +agg_vcgen_smooth_poly1.obj: ..\..\src\agg_vcgen_smooth_poly1.cpp + $(CXX) $** -o$@ + +agg_vcgen_stroke.obj: ..\..\src\agg_vcgen_stroke.cpp + $(CXX) $** -o$@ + +agg_vpgen_clip_polygon.obj: ..\..\src\agg_vpgen_clip_polygon.cpp + $(CXX) $** -o$@ + +agg_vpgen_clip_polyline.obj: ..\..\src\agg_vpgen_clip_polyline.cpp + $(CXX) $** -o$@ + +agg_vpgen_segmentator.obj: ..\..\src\agg_vpgen_segmentator.cpp + $(CXX) $** -o$@ + +agg_font_win32_tt.obj: ..\..\font_win32_tt\agg_font_win32_tt.cpp + $(CXX) $** -o$@ + +agg_bezier_ctrl.obj: ..\..\src\ctrl\agg_bezier_ctrl.cpp + $(CXX) $** -o$@ + +agg_cbox_ctrl.obj: ..\..\src\ctrl\agg_cbox_ctrl.cpp + $(CXX) $** -o$@ + +agg_gamma_ctrl.obj: ..\..\src\ctrl\agg_gamma_ctrl.cpp + $(CXX) $** -o$@ + +agg_gamma_spline.obj: ..\..\src\ctrl\agg_gamma_spline.cpp + $(CXX) $** -o$@ + +agg_polygon_ctrl.obj: ..\..\src\ctrl\agg_polygon_ctrl.cpp + $(CXX) $** -o$@ + +agg_rbox_ctrl.obj: ..\..\src\ctrl\agg_rbox_ctrl.cpp + $(CXX) $** -o$@ + +agg_scale_ctrl.obj: ..\..\src\ctrl\agg_scale_ctrl.cpp + $(CXX) $** -o$@ + +agg_slider_ctrl.obj: ..\..\src\ctrl\agg_slider_ctrl.cpp + $(CXX) $** -o$@ + +agg_spline_ctrl.obj: ..\..\src\ctrl\agg_spline_ctrl.cpp + $(CXX) $** -o$@ + +agg_platform_support.obj: ..\..\src\platform\win32\agg_platform_support.cpp + $(CXX) $** -o$@ + +agg_win32_bmp.obj: ..\..\src\platform\win32\agg_win32_bmp.cpp + $(CXX) $** -o$@ + +gpc.obj: ..\..\gpc\gpc.c + $(C) $(CFLAGS) $** -o$@ + +clean: + del *.obj + del agg.lib + del *.exe + del *.map + diff --git a/examples/win32_api_dmc/readme b/examples/win32_api_dmc/readme new file mode 100644 index 0000000..1d0ff49 --- /dev/null +++ b/examples/win32_api_dmc/readme @@ -0,0 +1,20 @@ +This is a makefile to build the demo examples with the Digital Mars C++. +Visit http://digitalmars.com/ for more info and to download the compiler. + +The compiler is very easy in use and doesn't require any installation +procedure. You just download and unzip it. + +Suppose you have unzipped it into the root directory: + +\dm\*.* + +That is, the full path to the compiler is \dm\bin\dmc.exe + +Then you simply run: + +\dm\bin\make + +That's it, it should build the examples, except for svg_test and freetype_test. +If you have a different directory with the compiler please modify the Makefile +accordingly (that's pertty easy). + diff --git a/font_freetype/Makefile.am b/font_freetype/Makefile.am new file mode 100644 index 0000000..8877d51 --- /dev/null +++ b/font_freetype/Makefile.am @@ -0,0 +1,11 @@ + +if ENABLE_FT +aggincludedir = $(includedir)/agg2 +agginclude_HEADERS = agg_font_freetype.h +lib_LTLIBRARIES = libaggfontfreetype.la + +libaggfontfreetype_la_LDFLAGS = -version-info @AGG_LIB_VERSION@ @FREETYPE_LIBS@ +libaggfontfreetype_la_SOURCES = agg_font_freetype.cpp +libaggfontfreetype_la_CXXFLAGS = -I$(top_srcdir)/include @FREETYPE_CFLAGS@ +endif + diff --git a/font_freetype/agg_font_freetype.cpp b/font_freetype/agg_font_freetype.cpp new file mode 100644 index 0000000..0afe9ab --- /dev/null +++ b/font_freetype/agg_font_freetype.cpp @@ -0,0 +1,1149 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + + +#include <cstdio> +#include <cstring> +#include "agg_font_freetype.h" +#include "agg_bitset_iterator.h" +#include "agg_renderer_scanline.h" + + +namespace agg +{ + + //------------------------------------------------------------------------------ + // + // This code implements the AUTODIN II polynomial + // The variable corresponding to the macro argument "crc" should + // be an unsigned long. + // Oroginal code by Spencer Garrett <srg@quick.com> + // + + // generated using the AUTODIN II polynomial + // x^32 + x^26 + x^23 + x^22 + x^16 + + // x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 + // + //------------------------------------------------------------------------------ + + static const unsigned crc32tab[256] = + { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, + }; + + + //------------------------------------------------------------------------------ + + static unsigned calc_crc32(const unsigned char* buf, unsigned size) + { + unsigned crc = (unsigned)~0; + const unsigned char* p; + unsigned len = 0; + unsigned nr = size; + + for (len += nr, p = buf; nr--; ++p) + { + crc = (crc >> 8) ^ crc32tab[(crc ^ *p) & 0xff]; + } + return ~crc; + } + + //------------------------------------------------------------------------ + static inline int dbl_to_plain_fx(double d) + { + return int(d * 65536.0); + } + + //------------------------------------------------------------------------ + static inline double int26p6_to_dbl(int p) + { + return double(p) / 64.0; + } + + //------------------------------------------------------------------------ + static inline int dbl_to_int26p6(double p) + { + return int(p * 64.0 + 0.5); + } + + + //------------------------------------------------------------------------ + template<class PathStorage> + bool decompose_ft_outline(const FT_Outline& outline, + bool flip_y, + const trans_affine& mtx, + PathStorage& path) + { + typedef typename PathStorage::value_type value_type; + + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + double x1, y1, x2, y2, x3, y3; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + int n; // index of contour in outline + int first; // index of first point in contour + char tag; // current point's state + + first = 0; + + for(n = 0; n < outline.n_contours; n++) + { + int last; // index of last point in contour + + last = outline.contours[n]; + limit = outline.points + last; + + v_start = outline.points[first]; + v_last = outline.points[last]; + + v_control = v_start; + + point = outline.points + first; + tags = outline.tags + first; + tag = FT_CURVE_TAG(tags[0]); + + // A contour cannot start with a cubic control point! + if(tag == FT_CURVE_TAG_CUBIC) return false; + + // check first point to determine origin + if( tag == FT_CURVE_TAG_CONIC) + { + // first point is conic control. Yes, this happens. + if(FT_CURVE_TAG(outline.tags[last]) == FT_CURVE_TAG_ON) + { + // start at last point if it is on the curve + v_start = v_last; + limit--; + } + else + { + // if both first and last points are conic, + // start at their middle and record its position + // for closure + v_start.x = (v_start.x + v_last.x) / 2; + v_start.y = (v_start.y + v_last.y) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + x1 = int26p6_to_dbl(v_start.x); + y1 = int26p6_to_dbl(v_start.y); + if(flip_y) y1 = -y1; + mtx.transform(&x1, &y1); + path.move_to(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1))); + + while(point < limit) + { + point++; + tags++; + + tag = FT_CURVE_TAG(tags[0]); + switch(tag) + { + case FT_CURVE_TAG_ON: // emit a single line_to + { + x1 = int26p6_to_dbl(point->x); + y1 = int26p6_to_dbl(point->y); + if(flip_y) y1 = -y1; + mtx.transform(&x1, &y1); + path.line_to(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1))); + //path.line_to(conv(point->x), flip_y ? -conv(point->y) : conv(point->y)); + continue; + } + + case FT_CURVE_TAG_CONIC: // consume conic arcs + { + v_control.x = point->x; + v_control.y = point->y; + + Do_Conic: + if(point < limit) + { + FT_Vector vec; + FT_Vector v_middle; + + point++; + tags++; + tag = FT_CURVE_TAG(tags[0]); + + vec.x = point->x; + vec.y = point->y; + + if(tag == FT_CURVE_TAG_ON) + { + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(vec.x); + y2 = int26p6_to_dbl(vec.y); + if(flip_y) { y1 = -y1; y2 = -y2; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2))); + continue; + } + + if(tag != FT_CURVE_TAG_CONIC) return false; + + v_middle.x = (v_control.x + vec.x) / 2; + v_middle.y = (v_control.y + vec.y) / 2; + + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(v_middle.x); + y2 = int26p6_to_dbl(v_middle.y); + if(flip_y) { y1 = -y1; y2 = -y2; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2))); + + //path.curve3(conv(v_control.x), + // flip_y ? -conv(v_control.y) : conv(v_control.y), + // conv(v_middle.x), + // flip_y ? -conv(v_middle.y) : conv(v_middle.y)); + + v_control = vec; + goto Do_Conic; + } + + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(v_start.x); + y2 = int26p6_to_dbl(v_start.y); + if(flip_y) { y1 = -y1; y2 = -y2; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2))); + + //path.curve3(conv(v_control.x), + // flip_y ? -conv(v_control.y) : conv(v_control.y), + // conv(v_start.x), + // flip_y ? -conv(v_start.y) : conv(v_start.y)); + goto Close; + } + + default: // FT_CURVE_TAG_CUBIC + { + FT_Vector vec1, vec2; + + if(point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) + { + return false; + } + + vec1.x = point[0].x; + vec1.y = point[0].y; + vec2.x = point[1].x; + vec2.y = point[1].y; + + point += 2; + tags += 2; + + if(point <= limit) + { + FT_Vector vec; + + vec.x = point->x; + vec.y = point->y; + + x1 = int26p6_to_dbl(vec1.x); + y1 = int26p6_to_dbl(vec1.y); + x2 = int26p6_to_dbl(vec2.x); + y2 = int26p6_to_dbl(vec2.y); + x3 = int26p6_to_dbl(vec.x); + y3 = int26p6_to_dbl(vec.y); + if(flip_y) { y1 = -y1; y2 = -y2; y3 = -y3; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + mtx.transform(&x3, &y3); + path.curve4(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2)), + value_type(dbl_to_int26p6(x3)), + value_type(dbl_to_int26p6(y3))); + + //path.curve4(conv(vec1.x), + // flip_y ? -conv(vec1.y) : conv(vec1.y), + // conv(vec2.x), + // flip_y ? -conv(vec2.y) : conv(vec2.y), + // conv(vec.x), + // flip_y ? -conv(vec.y) : conv(vec.y)); + continue; + } + + x1 = int26p6_to_dbl(vec1.x); + y1 = int26p6_to_dbl(vec1.y); + x2 = int26p6_to_dbl(vec2.x); + y2 = int26p6_to_dbl(vec2.y); + x3 = int26p6_to_dbl(v_start.x); + y3 = int26p6_to_dbl(v_start.y); + if(flip_y) { y1 = -y1; y2 = -y2; y3 = -y3; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + mtx.transform(&x3, &y3); + path.curve4(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2)), + value_type(dbl_to_int26p6(x3)), + value_type(dbl_to_int26p6(y3))); + + //path.curve4(conv(vec1.x), + // flip_y ? -conv(vec1.y) : conv(vec1.y), + // conv(vec2.x), + // flip_y ? -conv(vec2.y) : conv(vec2.y), + // conv(v_start.x), + // flip_y ? -conv(v_start.y) : conv(v_start.y)); + goto Close; + } + } + } + + path.close_polygon(); + + Close: + first = last + 1; + } + + return true; + } + + + + //------------------------------------------------------------------------ + template<class Scanline, class ScanlineStorage> + void decompose_ft_bitmap_mono(const FT_Bitmap& bitmap, + int x, int y, + bool flip_y, + Scanline& sl, + ScanlineStorage& storage) + { + int i; + const int8u* buf = (const int8u*)bitmap.buffer; + int pitch = bitmap.pitch; + sl.reset(x, x + bitmap.width); + storage.prepare(); + if(flip_y) + { + buf += bitmap.pitch * (bitmap.rows - 1); + y += bitmap.rows; + pitch = -pitch; + } + for(i = 0; i < bitmap.rows; i++) + { + sl.reset_spans(); + bitset_iterator bits(buf, 0); + int j; + for(j = 0; j < bitmap.width; j++) + { + if(bits.bit()) sl.add_cell(x + j, cover_full); + ++bits; + } + buf += pitch; + if(sl.num_spans()) + { + sl.finalize(y - i - 1); + storage.render(sl); + } + } + } + + + + //------------------------------------------------------------------------ + template<class Rasterizer, class Scanline, class ScanlineStorage> + void decompose_ft_bitmap_gray8(const FT_Bitmap& bitmap, + int x, int y, + bool flip_y, + Rasterizer& ras, + Scanline& sl, + ScanlineStorage& storage) + { + int i, j; + const int8u* buf = (const int8u*)bitmap.buffer; + int pitch = bitmap.pitch; + sl.reset(x, x + bitmap.width); + storage.prepare(); + if(flip_y) + { + buf += bitmap.pitch * (bitmap.rows - 1); + y += bitmap.rows; + pitch = -pitch; + } + for(i = 0; i < bitmap.rows; i++) + { + sl.reset_spans(); + const int8u* p = buf; + for(j = 0; j < bitmap.width; j++) + { + if(*p) sl.add_cell(x + j, ras.apply_gamma(*p)); + ++p; + } + buf += pitch; + if(sl.num_spans()) + { + sl.finalize(y - i - 1); + storage.render(sl); + } + } + } + + + + + + + + + + + + + + //------------------------------------------------------------------------ + font_engine_freetype_base::~font_engine_freetype_base() + { + unsigned i; + for(i = 0; i < m_num_faces; ++i) + { + delete [] m_face_names[i]; + FT_Done_Face(m_faces[i]); + } + delete [] m_face_names; + delete [] m_faces; + delete [] m_signature; + if(m_library_initialized) FT_Done_FreeType(m_library); + } + + + //------------------------------------------------------------------------ + font_engine_freetype_base::font_engine_freetype_base(bool flag32, + unsigned max_faces) : + m_flag32(flag32), + m_change_stamp(0), + m_last_error(0), + m_name(0), + m_name_len(256-16-1), + m_face_index(0), + m_char_map(FT_ENCODING_NONE), + m_signature(new char [256+256-16]), + m_height(0), + m_width(0), + m_hinting(true), + m_flip_y(false), + m_library_initialized(false), + m_library(0), + m_faces(new FT_Face [max_faces]), + m_face_names(new char* [max_faces]), + m_num_faces(0), + m_max_faces(max_faces), + m_cur_face(0), + m_resolution(0), + m_glyph_rendering(glyph_ren_native_gray8), + m_glyph_index(0), + m_data_size(0), + m_data_type(glyph_data_invalid), + m_bounds(1,1,0,0), + m_advance_x(0.0), + m_advance_y(0.0), + + m_path16(), + m_path32(), + m_curves16(m_path16), + m_curves32(m_path32), + m_scanline_aa(), + m_scanline_bin(), + m_scanlines_aa(), + m_scanlines_bin(), + m_rasterizer() + { + m_curves16.approximation_scale(4.0); + m_curves32.approximation_scale(4.0); + m_last_error = FT_Init_FreeType(&m_library); + if(m_last_error == 0) m_library_initialized = true; + } + + + + //------------------------------------------------------------------------ + void font_engine_freetype_base::resolution(unsigned dpi) + { + m_resolution = dpi; + update_char_size(); + } + + + //------------------------------------------------------------------------ + int font_engine_freetype_base::find_face(const char* face_name) const + { + unsigned i; + for(i = 0; i < m_num_faces; ++i) + { + if(std::strcmp(face_name, m_face_names[i]) == 0) return i; + } + return -1; + } + + + //------------------------------------------------------------------------ + double font_engine_freetype_base::ascender() const + { + if(m_cur_face) + { + return m_cur_face->ascender * height() / m_cur_face->height; + } + return 0.0; + } + + //------------------------------------------------------------------------ + double font_engine_freetype_base::descender() const + { + if(m_cur_face) + { + return m_cur_face->descender * height() / m_cur_face->height; + } + return 0.0; + } + + + //------------------------------------------------------------------------ + bool font_engine_freetype_base::load_font(const char* font_name, + unsigned face_index, + glyph_rendering ren_type, + const char* font_mem, + const long font_mem_size) + { + bool ret = false; + + if(m_library_initialized) + { + m_last_error = 0; + + int idx = find_face(font_name); + if(idx >= 0) + { + m_cur_face = m_faces[idx]; + m_name = m_face_names[idx]; + } + else + { + if(m_num_faces >= m_max_faces) + { + delete [] m_face_names[0]; + FT_Done_Face(m_faces[0]); + std::memcpy(m_faces, + m_faces + 1, + (m_max_faces - 1) * sizeof(FT_Face)); + std::memcpy(m_face_names, + m_face_names + 1, + (m_max_faces - 1) * sizeof(char*)); + m_num_faces = m_max_faces - 1; + } + + if (font_mem && font_mem_size) + { + m_last_error = FT_New_Memory_Face(m_library, + (const FT_Byte*)font_mem, + font_mem_size, + face_index, + &m_faces[m_num_faces]); + } + else + { + m_last_error = FT_New_Face(m_library, + font_name, + face_index, + &m_faces[m_num_faces]); + } + + if(m_last_error == 0) + { + m_face_names[m_num_faces] = new char [std::strlen(font_name) + 1]; + std::strcpy(m_face_names[m_num_faces], font_name); + m_cur_face = m_faces[m_num_faces]; + m_name = m_face_names[m_num_faces]; + ++m_num_faces; + } + else + { + m_face_names[m_num_faces] = 0; + m_cur_face = 0; + m_name = 0; + } + } + + + if(m_last_error == 0) + { + ret = true; + + switch(ren_type) + { + case glyph_ren_native_mono: + m_glyph_rendering = glyph_ren_native_mono; + break; + + case glyph_ren_native_gray8: + m_glyph_rendering = glyph_ren_native_gray8; + break; + + case glyph_ren_outline: + if(FT_IS_SCALABLE(m_cur_face)) + { + m_glyph_rendering = glyph_ren_outline; + } + else + { + m_glyph_rendering = glyph_ren_native_gray8; + } + break; + + case glyph_ren_agg_mono: + if(FT_IS_SCALABLE(m_cur_face)) + { + m_glyph_rendering = glyph_ren_agg_mono; + } + else + { + m_glyph_rendering = glyph_ren_native_mono; + } + break; + + case glyph_ren_agg_gray8: + if(FT_IS_SCALABLE(m_cur_face)) + { + m_glyph_rendering = glyph_ren_agg_gray8; + } + else + { + m_glyph_rendering = glyph_ren_native_gray8; + } + break; + } + update_signature(); + } + } + return ret; + } + + + //------------------------------------------------------------------------ + bool font_engine_freetype_base::attach(const char* file_name) + { + if(m_cur_face) + { + m_last_error = FT_Attach_File(m_cur_face, file_name); + return m_last_error == 0; + } + return false; + } + + //------------------------------------------------------------------------ + unsigned font_engine_freetype_base::num_faces() const + { + if(m_cur_face) + { + return m_cur_face->num_faces; + } + return 0; + } + + //------------------------------------------------------------------------ + bool font_engine_freetype_base::char_map(FT_Encoding map) + { + if(m_cur_face) + { + m_last_error = FT_Select_Charmap(m_cur_face, map); + if(m_last_error == 0) + { + m_char_map = map; + update_signature(); + return true; + } + } + return false; + } + + //------------------------------------------------------------------------ + bool font_engine_freetype_base::height(double h) + { + m_height = int(h * 64.0); + if(m_cur_face) + { + update_char_size(); + return true; + } + return false; + } + + //------------------------------------------------------------------------ + bool font_engine_freetype_base::width(double w) + { + m_width = int(w * 64.0); + if(m_cur_face) + { + update_char_size(); + return true; + } + return false; + } + + //------------------------------------------------------------------------ + void font_engine_freetype_base::hinting(bool h) + { + m_hinting = h; + if(m_cur_face) + { + update_signature(); + } + } + + //------------------------------------------------------------------------ + void font_engine_freetype_base::flip_y(bool f) + { + m_flip_y = f; + if(m_cur_face) + { + update_signature(); + } + } + + //------------------------------------------------------------------------ + void font_engine_freetype_base::transform(const trans_affine& affine) + { + m_affine = affine; + if(m_cur_face) + { + update_signature(); + } + } + + //------------------------------------------------------------------------ + void font_engine_freetype_base::update_signature() + { + if(m_cur_face && m_name) + { + unsigned name_len = std::strlen(m_name); + if(name_len > m_name_len) + { + delete [] m_signature; + m_signature = new char [name_len + 32 + 256]; + m_name_len = name_len + 32 - 1; + } + + unsigned gamma_hash = 0; + if(m_glyph_rendering == glyph_ren_native_gray8 || + m_glyph_rendering == glyph_ren_agg_mono || + m_glyph_rendering == glyph_ren_agg_gray8) + { + unsigned char gamma_table[rasterizer_scanline_aa<>::aa_scale]; + unsigned i; + for(i = 0; i < rasterizer_scanline_aa<>::aa_scale; ++i) + { + gamma_table[i] = m_rasterizer.apply_gamma(i); + } + gamma_hash = calc_crc32(gamma_table, sizeof(gamma_table)); + } + + std::sprintf(m_signature, + "%s,%u,%d,%d,%d:%dx%d,%d,%d,%08X", + m_name, + m_char_map, + m_face_index, + int(m_glyph_rendering), + m_resolution, + m_height, + m_width, + int(m_hinting), + int(m_flip_y), + gamma_hash); + if(m_glyph_rendering == glyph_ren_outline || + m_glyph_rendering == glyph_ren_agg_mono || + m_glyph_rendering == glyph_ren_agg_gray8) + { + double mtx[6]; + char buf[100]; + m_affine.store_to(mtx); + std::sprintf(buf, ",%08X%08X%08X%08X%08X%08X", + dbl_to_plain_fx(mtx[0]), + dbl_to_plain_fx(mtx[1]), + dbl_to_plain_fx(mtx[2]), + dbl_to_plain_fx(mtx[3]), + dbl_to_plain_fx(mtx[4]), + dbl_to_plain_fx(mtx[5])); + std::strcat(m_signature, buf); + } + ++m_change_stamp; + } + } + + + //------------------------------------------------------------------------ + void font_engine_freetype_base::update_char_size() + { + if(m_cur_face) + { + if(m_resolution) + { + FT_Set_Char_Size(m_cur_face, + m_width, // char_width in 1/64th of points + m_height, // char_height in 1/64th of points + m_resolution, // horizontal device resolution + m_resolution); // vertical device resolution + } + else + { + FT_Set_Pixel_Sizes(m_cur_face, + m_width >> 6, // pixel_width + m_height >> 6); // pixel_height + } + update_signature(); + } + } + + + + + + //------------------------------------------------------------------------ + bool font_engine_freetype_base::prepare_glyph(unsigned glyph_code) + { + m_glyph_index = FT_Get_Char_Index(m_cur_face, glyph_code); + m_last_error = FT_Load_Glyph(m_cur_face, + m_glyph_index, + m_hinting ? FT_LOAD_DEFAULT : FT_LOAD_NO_HINTING); +// m_hinting ? FT_LOAD_FORCE_AUTOHINT : FT_LOAD_NO_HINTING); + if(m_last_error == 0) + { + switch(m_glyph_rendering) + { + case glyph_ren_native_mono: + m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_MONO); + if(m_last_error == 0) + { + decompose_ft_bitmap_mono(m_cur_face->glyph->bitmap, + m_cur_face->glyph->bitmap_left, + m_flip_y ? -m_cur_face->glyph->bitmap_top : + m_cur_face->glyph->bitmap_top, + m_flip_y, + m_scanline_bin, + m_scanlines_bin); + m_bounds.x1 = m_scanlines_bin.min_x(); + m_bounds.y1 = m_scanlines_bin.min_y(); + m_bounds.x2 = m_scanlines_bin.max_x() + 1; + m_bounds.y2 = m_scanlines_bin.max_y() + 1; + m_data_size = m_scanlines_bin.byte_size(); + m_data_type = glyph_data_mono; + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); + return true; + } + break; + + + case glyph_ren_native_gray8: + m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_NORMAL); + if(m_last_error == 0) + { + decompose_ft_bitmap_gray8(m_cur_face->glyph->bitmap, + m_cur_face->glyph->bitmap_left, + m_flip_y ? -m_cur_face->glyph->bitmap_top : + m_cur_face->glyph->bitmap_top, + m_flip_y, + m_rasterizer, + m_scanline_aa, + m_scanlines_aa); + m_bounds.x1 = m_scanlines_aa.min_x(); + m_bounds.y1 = m_scanlines_aa.min_y(); + m_bounds.x2 = m_scanlines_aa.max_x() + 1; + m_bounds.y2 = m_scanlines_aa.max_y() + 1; + m_data_size = m_scanlines_aa.byte_size(); + m_data_type = glyph_data_gray8; + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); + return true; + } + break; + + + case glyph_ren_outline: + if(m_last_error == 0) + { + if(m_flag32) + { + m_path32.remove_all(); + if(decompose_ft_outline(m_cur_face->glyph->outline, + m_flip_y, + m_affine, + m_path32)) + { + rect_d bnd = m_path32.bounding_rect(); + m_data_size = m_path32.byte_size(); + m_data_type = glyph_data_outline; + m_bounds.x1 = int(floor(bnd.x1)); + m_bounds.y1 = int(floor(bnd.y1)); + m_bounds.x2 = int(ceil(bnd.x2)); + m_bounds.y2 = int(ceil(bnd.y2)); + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); + m_affine.transform(&m_advance_x, &m_advance_y); + return true; + } + } + else + { + m_path16.remove_all(); + if(decompose_ft_outline(m_cur_face->glyph->outline, + m_flip_y, + m_affine, + m_path16)) + { + rect_d bnd = m_path16.bounding_rect(); + m_data_size = m_path16.byte_size(); + m_data_type = glyph_data_outline; + m_bounds.x1 = int(floor(bnd.x1)); + m_bounds.y1 = int(floor(bnd.y1)); + m_bounds.x2 = int(ceil(bnd.x2)); + m_bounds.y2 = int(ceil(bnd.y2)); + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); + m_affine.transform(&m_advance_x, &m_advance_y); + return true; + } + } + } + return false; + + case glyph_ren_agg_mono: + if(m_last_error == 0) + { + m_rasterizer.reset(); + if(m_flag32) + { + m_path32.remove_all(); + decompose_ft_outline(m_cur_face->glyph->outline, + m_flip_y, + m_affine, + m_path32); + m_rasterizer.add_path(m_curves32); + } + else + { + m_path16.remove_all(); + decompose_ft_outline(m_cur_face->glyph->outline, + m_flip_y, + m_affine, + m_path16); + m_rasterizer.add_path(m_curves16); + } + m_scanlines_bin.prepare(); // Remove all + render_scanlines(m_rasterizer, m_scanline_bin, m_scanlines_bin); + m_bounds.x1 = m_scanlines_bin.min_x(); + m_bounds.y1 = m_scanlines_bin.min_y(); + m_bounds.x2 = m_scanlines_bin.max_x() + 1; + m_bounds.y2 = m_scanlines_bin.max_y() + 1; + m_data_size = m_scanlines_bin.byte_size(); + m_data_type = glyph_data_mono; + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); + m_affine.transform(&m_advance_x, &m_advance_y); + return true; + } + return false; + + + case glyph_ren_agg_gray8: + if(m_last_error == 0) + { + m_rasterizer.reset(); + if(m_flag32) + { + m_path32.remove_all(); + decompose_ft_outline(m_cur_face->glyph->outline, + m_flip_y, + m_affine, + m_path32); + m_rasterizer.add_path(m_curves32); + } + else + { + m_path16.remove_all(); + decompose_ft_outline(m_cur_face->glyph->outline, + m_flip_y, + m_affine, + m_path16); + m_rasterizer.add_path(m_curves16); + } + m_scanlines_aa.prepare(); // Remove all + render_scanlines(m_rasterizer, m_scanline_aa, m_scanlines_aa); + m_bounds.x1 = m_scanlines_aa.min_x(); + m_bounds.y1 = m_scanlines_aa.min_y(); + m_bounds.x2 = m_scanlines_aa.max_x() + 1; + m_bounds.y2 = m_scanlines_aa.max_y() + 1; + m_data_size = m_scanlines_aa.byte_size(); + m_data_type = glyph_data_gray8; + m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x); + m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y); + m_affine.transform(&m_advance_x, &m_advance_y); + return true; + } + return false; + } + } + return false; + } + + + + + //------------------------------------------------------------------------ + void font_engine_freetype_base::write_glyph_to(int8u* data) const + { + if(data && m_data_size) + { + switch(m_data_type) + { + default: return; + case glyph_data_mono: m_scanlines_bin.serialize(data); break; + case glyph_data_gray8: m_scanlines_aa.serialize(data); break; + case glyph_data_outline: + if(m_flag32) + { + m_path32.serialize(data); + } + else + { + m_path16.serialize(data); + } + break; + case glyph_data_invalid: break; + } + } + } + + + + //------------------------------------------------------------------------ + bool font_engine_freetype_base::add_kerning(unsigned first, unsigned second, + double* x, double* y) + { + if(m_cur_face && first && second && FT_HAS_KERNING(m_cur_face)) + { + FT_Vector delta; + FT_Get_Kerning(m_cur_face, first, second, + FT_KERNING_DEFAULT, &delta); + double dx = int26p6_to_dbl(delta.x); + double dy = int26p6_to_dbl(delta.y); + if(m_glyph_rendering == glyph_ren_outline || + m_glyph_rendering == glyph_ren_agg_mono || + m_glyph_rendering == glyph_ren_agg_gray8) + { + m_affine.transform_2x2(&dx, &dy); + } + *x += dx; + *y += dy; + + return true; + } + return false; + } + + + +} + + diff --git a/font_freetype/agg_font_freetype.h b/font_freetype/agg_font_freetype.h new file mode 100644 index 0000000..273243c --- /dev/null +++ b/font_freetype/agg_font_freetype.h @@ -0,0 +1,196 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// See implementation agg_font_freetype.cpp +// +//---------------------------------------------------------------------------- + +#ifndef AGG_FONT_FREETYPE_INCLUDED +#define AGG_FONT_FREETYPE_INCLUDED + +#include <ft2build.h> +#include FT_FREETYPE_H + + +#include "agg_scanline_storage_aa.h" +#include "agg_scanline_storage_bin.h" +#include "agg_scanline_u.h" +#include "agg_scanline_bin.h" +#include "agg_path_storage_integer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_conv_curve.h" +#include "agg_font_cache_manager.h" +#include "agg_trans_affine.h" + +namespace agg +{ + + + //-----------------------------------------------font_engine_freetype_base + class font_engine_freetype_base + { + public: + //-------------------------------------------------------------------- + typedef serialized_scanlines_adaptor_aa<int8u> gray8_adaptor_type; + typedef serialized_scanlines_adaptor_bin mono_adaptor_type; + typedef scanline_storage_aa8 scanlines_aa_type; + typedef scanline_storage_bin scanlines_bin_type; + + //-------------------------------------------------------------------- + ~font_engine_freetype_base(); + font_engine_freetype_base(bool flag32, unsigned max_faces = 32); + + // Set font parameters + //-------------------------------------------------------------------- + void resolution(unsigned dpi); + bool load_font(const char* font_name, unsigned face_index, glyph_rendering ren_type, + const char* font_mem = 0, const long font_mem_size = 0); + bool attach(const char* file_name); + bool char_map(FT_Encoding map); + bool height(double h); + bool width(double w); + void hinting(bool h); + void flip_y(bool f); + void transform(const trans_affine& affine); + + // Set Gamma + //-------------------------------------------------------------------- + template<class GammaF> void gamma(const GammaF& f) + { + m_rasterizer.gamma(f); + } + + // Accessors + //-------------------------------------------------------------------- + int last_error() const { return m_last_error; } + unsigned resolution() const { return m_resolution; } + const char* name() const { return m_name; } + unsigned num_faces() const; + FT_Encoding char_map() const { return m_char_map; } + double height() const { return double(m_height) / 64.0; } + double width() const { return double(m_width) / 64.0; } + double ascender() const; + double descender() const; + bool hinting() const { return m_hinting; } + bool flip_y() const { return m_flip_y; } + + + // Interface mandatory to implement for font_cache_manager + //-------------------------------------------------------------------- + const char* font_signature() const { return m_signature; } + int change_stamp() const { return m_change_stamp; } + + bool prepare_glyph(unsigned glyph_code); + unsigned glyph_index() const { return m_glyph_index; } + unsigned data_size() const { return m_data_size; } + glyph_data_type data_type() const { return m_data_type; } + const rect_i& bounds() const { return m_bounds; } + double advance_x() const { return m_advance_x; } + double advance_y() const { return m_advance_y; } + void write_glyph_to(int8u* data) const; + bool add_kerning(unsigned first, unsigned second, + double* x, double* y); + + private: + font_engine_freetype_base(const font_engine_freetype_base&); + const font_engine_freetype_base& operator = (const font_engine_freetype_base&); + + void update_char_size(); + void update_signature(); + int find_face(const char* face_name) const; + + bool m_flag32; + int m_change_stamp; + int m_last_error; + char* m_name; + unsigned m_name_len; + unsigned m_face_index; + FT_Encoding m_char_map; + char* m_signature; + unsigned m_height; + unsigned m_width; + bool m_hinting; + bool m_flip_y; + bool m_library_initialized; + FT_Library m_library; // handle to library + FT_Face* m_faces; // A pool of font faces + char** m_face_names; + unsigned m_num_faces; + unsigned m_max_faces; + FT_Face m_cur_face; // handle to the current face object + int m_resolution; + glyph_rendering m_glyph_rendering; + unsigned m_glyph_index; + unsigned m_data_size; + glyph_data_type m_data_type; + rect_i m_bounds; + double m_advance_x; + double m_advance_y; + trans_affine m_affine; + + path_storage_integer<int16, 6> m_path16; + path_storage_integer<int32, 6> m_path32; + conv_curve<path_storage_integer<int16, 6> > m_curves16; + conv_curve<path_storage_integer<int32, 6> > m_curves32; + scanline_u8 m_scanline_aa; + scanline_bin m_scanline_bin; + scanlines_aa_type m_scanlines_aa; + scanlines_bin_type m_scanlines_bin; + rasterizer_scanline_aa<> m_rasterizer; + }; + + + + + //------------------------------------------------font_engine_freetype_int16 + // This class uses values of type int16 (10.6 format) for the vector cache. + // The vector cache is compact, but when rendering glyphs of height + // more that 200 there integer overflow can occur. + // + class font_engine_freetype_int16 : public font_engine_freetype_base + { + public: + typedef serialized_integer_path_adaptor<int16, 6> path_adaptor_type; + typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type; + typedef font_engine_freetype_base::mono_adaptor_type mono_adaptor_type; + typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type; + typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type; + + font_engine_freetype_int16(unsigned max_faces = 32) : + font_engine_freetype_base(false, max_faces) {} + }; + + //------------------------------------------------font_engine_freetype_int32 + // This class uses values of type int32 (26.6 format) for the vector cache. + // The vector cache is twice larger than in font_engine_freetype_int16, + // but it allows you to render glyphs of very large sizes. + // + class font_engine_freetype_int32 : public font_engine_freetype_base + { + public: + typedef serialized_integer_path_adaptor<int32, 6> path_adaptor_type; + typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type; + typedef font_engine_freetype_base::mono_adaptor_type mono_adaptor_type; + typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type; + typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type; + + font_engine_freetype_int32(unsigned max_faces = 32) : + font_engine_freetype_base(true, max_faces) {} + }; + + +} + +#endif diff --git a/font_freetype/agg_font_freetype2.cpp b/font_freetype/agg_font_freetype2.cpp new file mode 100644 index 0000000..27c1670 --- /dev/null +++ b/font_freetype/agg_font_freetype2.cpp @@ -0,0 +1,877 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include <cstdio> +#include <cstring> +#include <freetype/ftmodapi.h> +#include "agg_font_freetype2.h" +#include "agg_bitset_iterator.h" +#include "agg_renderer_scanline.h" + + +namespace agg { +namespace fman { + + //------------------------------------------------------------------------------ + // + // This code implements the AUTODIN II polynomial + // The variable corresponding to the macro argument "crc" should + // be an unsigned long. + // Oroginal code by Spencer Garrett <srg@quick.com> + // + + // generated using the AUTODIN II polynomial + // x^32 + x^26 + x^23 + x^22 + x^16 + + // x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 + // + //------------------------------------------------------------------------------ + + static const unsigned crc32tab[256] = + { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, + }; + + + //------------------------------------------------------------------------------ + + static unsigned calc_crc32(const unsigned char* buf, unsigned size) + { + unsigned crc = (unsigned)~0; + const unsigned char* p; + unsigned len = 0; + unsigned nr = size; + + for (len += nr, p = buf; nr--; ++p) + { + crc = (crc >> 8) ^ crc32tab[(crc ^ *p) & 0xff]; + } + return ~crc; + } + + //------------------------------------------------------------------------ + static inline int dbl_to_plain_fx(double d) + { + return int(d * 65536.0); + } + + //------------------------------------------------------------------------ + static inline double int26p6_to_dbl(int p) + { + return double(p) / 64.0; + } + + //------------------------------------------------------------------------ + static inline int dbl_to_int26p6(double p) + { + return int(p * 64.0 + 0.5); + } + + + //------------------------------------------------------------------------ + template<class PathStorage> + bool decompose_ft_outline(const FT_Outline& outline, + bool flip_y, + const trans_affine& mtx, + PathStorage& path) + { + typedef typename PathStorage::value_type value_type; + + FT_Vector v_last; + FT_Vector v_control; + FT_Vector v_start; + double x1, y1, x2, y2, x3, y3; + + FT_Vector* point; + FT_Vector* limit; + char* tags; + + int n; // index of contour in outline + int first; // index of first point in contour + char tag; // current point's state + + first = 0; + + for(n = 0; n < outline.n_contours; n++) + { + int last; // index of last point in contour + + last = outline.contours[n]; + limit = outline.points + last; + + v_start = outline.points[first]; + v_last = outline.points[last]; + + v_control = v_start; + + point = outline.points + first; + tags = outline.tags + first; + tag = FT_CURVE_TAG(tags[0]); + + // A contour cannot start with a cubic control point! + if(tag == FT_CURVE_TAG_CUBIC) return false; + + // check first point to determine origin + if( tag == FT_CURVE_TAG_CONIC) + { + // first point is conic control. Yes, this happens. + if(FT_CURVE_TAG(outline.tags[last]) == FT_CURVE_TAG_ON) + { + // start at last point if it is on the curve + v_start = v_last; + limit--; + } + else + { + // if both first and last points are conic, + // start at their middle and record its position + // for closure + v_start.x = (v_start.x + v_last.x) / 2; + v_start.y = (v_start.y + v_last.y) / 2; + + v_last = v_start; + } + point--; + tags--; + } + + x1 = int26p6_to_dbl(v_start.x); + y1 = int26p6_to_dbl(v_start.y); + if(flip_y) y1 = -y1; + mtx.transform(&x1, &y1); + path.move_to(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1))); + + while(point < limit) + { + point++; + tags++; + + tag = FT_CURVE_TAG(tags[0]); + switch(tag) + { + case FT_CURVE_TAG_ON: // emit a single line_to + { + x1 = int26p6_to_dbl(point->x); + y1 = int26p6_to_dbl(point->y); + if(flip_y) y1 = -y1; + mtx.transform(&x1, &y1); + path.line_to(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1))); + //path.line_to(conv(point->x), flip_y ? -conv(point->y) : conv(point->y)); + continue; + } + + case FT_CURVE_TAG_CONIC: // consume conic arcs + { + v_control.x = point->x; + v_control.y = point->y; + + Do_Conic: + if(point < limit) + { + FT_Vector vec; + FT_Vector v_middle; + + point++; + tags++; + tag = FT_CURVE_TAG(tags[0]); + + vec.x = point->x; + vec.y = point->y; + + if(tag == FT_CURVE_TAG_ON) + { + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(vec.x); + y2 = int26p6_to_dbl(vec.y); + if(flip_y) { y1 = -y1; y2 = -y2; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2))); + continue; + } + + if(tag != FT_CURVE_TAG_CONIC) return false; + + v_middle.x = (v_control.x + vec.x) / 2; + v_middle.y = (v_control.y + vec.y) / 2; + + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(v_middle.x); + y2 = int26p6_to_dbl(v_middle.y); + if(flip_y) { y1 = -y1; y2 = -y2; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2))); + + //path.curve3(conv(v_control.x), + // flip_y ? -conv(v_control.y) : conv(v_control.y), + // conv(v_middle.x), + // flip_y ? -conv(v_middle.y) : conv(v_middle.y)); + + v_control = vec; + goto Do_Conic; + } + + x1 = int26p6_to_dbl(v_control.x); + y1 = int26p6_to_dbl(v_control.y); + x2 = int26p6_to_dbl(v_start.x); + y2 = int26p6_to_dbl(v_start.y); + if(flip_y) { y1 = -y1; y2 = -y2; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + path.curve3(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2))); + + //path.curve3(conv(v_control.x), + // flip_y ? -conv(v_control.y) : conv(v_control.y), + // conv(v_start.x), + // flip_y ? -conv(v_start.y) : conv(v_start.y)); + goto Close; + } + + default: // FT_CURVE_TAG_CUBIC + { + FT_Vector vec1, vec2; + + if(point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) + { + return false; + } + + vec1.x = point[0].x; + vec1.y = point[0].y; + vec2.x = point[1].x; + vec2.y = point[1].y; + + point += 2; + tags += 2; + + if(point <= limit) + { + FT_Vector vec; + + vec.x = point->x; + vec.y = point->y; + + x1 = int26p6_to_dbl(vec1.x); + y1 = int26p6_to_dbl(vec1.y); + x2 = int26p6_to_dbl(vec2.x); + y2 = int26p6_to_dbl(vec2.y); + x3 = int26p6_to_dbl(vec.x); + y3 = int26p6_to_dbl(vec.y); + if(flip_y) { y1 = -y1; y2 = -y2; y3 = -y3; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + mtx.transform(&x3, &y3); + path.curve4(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2)), + value_type(dbl_to_int26p6(x3)), + value_type(dbl_to_int26p6(y3))); + + //path.curve4(conv(vec1.x), + // flip_y ? -conv(vec1.y) : conv(vec1.y), + // conv(vec2.x), + // flip_y ? -conv(vec2.y) : conv(vec2.y), + // conv(vec.x), + // flip_y ? -conv(vec.y) : conv(vec.y)); + continue; + } + + x1 = int26p6_to_dbl(vec1.x); + y1 = int26p6_to_dbl(vec1.y); + x2 = int26p6_to_dbl(vec2.x); + y2 = int26p6_to_dbl(vec2.y); + x3 = int26p6_to_dbl(v_start.x); + y3 = int26p6_to_dbl(v_start.y); + if(flip_y) { y1 = -y1; y2 = -y2; y3 = -y3; } + mtx.transform(&x1, &y1); + mtx.transform(&x2, &y2); + mtx.transform(&x3, &y3); + path.curve4(value_type(dbl_to_int26p6(x1)), + value_type(dbl_to_int26p6(y1)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2)), + value_type(dbl_to_int26p6(x3)), + value_type(dbl_to_int26p6(y3))); + + //path.curve4(conv(vec1.x), + // flip_y ? -conv(vec1.y) : conv(vec1.y), + // conv(vec2.x), + // flip_y ? -conv(vec2.y) : conv(vec2.y), + // conv(v_start.x), + // flip_y ? -conv(v_start.y) : conv(v_start.y)); + goto Close; + } + } + } + + path.close_polygon(); + + Close: + first = last + 1; + } + + return true; + } + + + + //------------------------------------------------------------------------ + template<class Scanline, class ScanlineStorage> + void decompose_ft_bitmap_mono(const FT_Bitmap& bitmap, + int x, int y, + bool flip_y, + Scanline& sl, + ScanlineStorage& storage) + { + int i; + const int8u* buf = (const int8u*)bitmap.buffer; + int pitch = bitmap.pitch; + sl.reset(x, x + bitmap.width); + storage.prepare(); + if(flip_y) + { + buf += bitmap.pitch * (bitmap.rows - 1); + y += bitmap.rows; + pitch = -pitch; + } + for(i = 0; i < bitmap.rows; i++) + { + sl.reset_spans(); + bitset_iterator bits(buf, 0); + int j; + for(j = 0; j < bitmap.width; j++) + { + if(bits.bit()) sl.add_cell(x + j, cover_full); + ++bits; + } + buf += pitch; + if(sl.num_spans()) + { + sl.finalize(y - i - 1); + storage.render(sl); + } + } + } + + + + //------------------------------------------------------------------------ + template<class Rasterizer, class Scanline, class ScanlineStorage> + void decompose_ft_bitmap_gray8(const FT_Bitmap& bitmap, + int x, int y, + bool flip_y, + Rasterizer& ras, + Scanline& sl, + ScanlineStorage& storage) + { + int i, j; + const int8u* buf = (const int8u*)bitmap.buffer; + int pitch = bitmap.pitch; + sl.reset(x, x + bitmap.width); + storage.prepare(); + if(flip_y) + { + buf += bitmap.pitch * (bitmap.rows - 1); + y += bitmap.rows; + pitch = -pitch; + } + for(i = 0; i < bitmap.rows; i++) + { + sl.reset_spans(); + const int8u* p = buf; + for(j = 0; j < bitmap.width; j++) + { + if(*p) sl.add_cell(x + j, ras.apply_gamma(*p)); + ++p; + } + buf += pitch; + if(sl.num_spans()) + { + sl.finalize(y - i - 1); + storage.render(sl); + } + } + } + + + + + + + + + //------------------------------------------------------------------------ + bool font_engine_freetype_base::loaded_face::prepare_glyph(unsigned glyph_code, prepared_glyph *prepared) const + { + bool success=false; + prepared->glyph_index = FT_Get_Char_Index(m_ft_face, glyph_code); + int error = FT_Load_Glyph(m_ft_face, + prepared->glyph_index, + m_hinting ? FT_LOAD_DEFAULT : FT_LOAD_NO_HINTING); + // m_hinting ? FT_LOAD_FORCE_AUTOHINT : FT_LOAD_NO_HINTING); + if(error == 0) + { + prepared->glyph_code=glyph_code; + switch(m_rendering) + { + case glyph_ren_native_mono: + error = FT_Render_Glyph(m_ft_face->glyph, FT_RENDER_MODE_MONO); + if(error == 0) + { + decompose_ft_bitmap_mono(m_ft_face->glyph->bitmap, + m_ft_face->glyph->bitmap_left, + m_flip_y ? -m_ft_face->glyph->bitmap_top : + m_ft_face->glyph->bitmap_top, + m_flip_y, + m_engine.m_scanline_bin, + m_engine.m_scanlines_bin); + prepared->bounds.x1 = m_engine.m_scanlines_bin.min_x(); + prepared->bounds.y1 = m_engine.m_scanlines_bin.min_y(); + prepared->bounds.x2 = m_engine.m_scanlines_bin.max_x() + 1; + prepared->bounds.y2 = m_engine.m_scanlines_bin.max_y() + 1; + prepared->data_size = m_engine.m_scanlines_bin.byte_size(); + prepared->data_type = glyph_data_mono; + prepared->advance_x = int26p6_to_dbl(m_ft_face->glyph->advance.x); + prepared->advance_y = int26p6_to_dbl(m_ft_face->glyph->advance.y); + success=true; + } + break; + + + case glyph_ren_native_gray8: + error = FT_Render_Glyph(m_ft_face->glyph, FT_RENDER_MODE_NORMAL); + if(error == 0) + { + decompose_ft_bitmap_gray8(m_ft_face->glyph->bitmap, + m_ft_face->glyph->bitmap_left, + m_flip_y ? -m_ft_face->glyph->bitmap_top : + m_ft_face->glyph->bitmap_top, + m_flip_y, + m_engine.m_rasterizer, + m_engine.m_scanline_aa, + m_engine.m_scanlines_aa); + prepared->data_size = m_engine.m_scanlines_aa.byte_size(); + prepared->data_type = glyph_data_gray8; + prepared->advance_x = int26p6_to_dbl(m_ft_face->glyph->advance.x); + prepared->advance_y = int26p6_to_dbl(m_ft_face->glyph->advance.y); + if( m_ft_face->glyph->bitmap.rows!=0 && + m_ft_face->glyph->bitmap.width!=0 ) + { + prepared->bounds.x1 = m_engine.m_scanlines_aa.min_x(); + prepared->bounds.y1 = m_engine.m_scanlines_aa.min_y(); + prepared->bounds.x2 = m_engine.m_scanlines_aa.max_x() + 1; + prepared->bounds.y2 = m_engine.m_scanlines_aa.max_y() + 1; + } + else + { + prepared->bounds.x1 = 0; + prepared->bounds.y1 = 0; + prepared->bounds.x2 = prepared->advance_x; + prepared->bounds.y2 = 0; + } + success=true; + } + break; + + + case glyph_ren_outline: + if(error == 0) + { + if(m_engine.m_flag32) + { + m_engine.m_path32.remove_all(); + if(decompose_ft_outline(m_ft_face->glyph->outline, + m_flip_y, + m_affine, + m_engine.m_path32)) + { + rect_d bnd = m_engine.m_path32.bounding_rect(); + prepared->data_size = m_engine.m_path32.byte_size(); + prepared->data_type = glyph_data_outline; + prepared->bounds.x1 = int(floor(bnd.x1)); + prepared->bounds.y1 = int(floor(bnd.y1)); + prepared->bounds.x2 = int(ceil(bnd.x2)); + prepared->bounds.y2 = int(ceil(bnd.y2)); + prepared->advance_x = int26p6_to_dbl(m_ft_face->glyph->advance.x); + prepared->advance_y = int26p6_to_dbl(m_ft_face->glyph->advance.y); + m_affine.transform(&prepared->advance_x, &prepared->advance_y); + success=true; + } + } + else + { + m_engine.m_path16.remove_all(); + if(decompose_ft_outline(m_ft_face->glyph->outline, + m_flip_y, + m_affine, + m_engine.m_path16)) + { + rect_d bnd = m_engine.m_path16.bounding_rect(); + prepared->data_size = m_engine.m_path16.byte_size(); + prepared->data_type = glyph_data_outline; + prepared->bounds.x1 = int(floor(bnd.x1)); + prepared->bounds.y1 = int(floor(bnd.y1)); + prepared->bounds.x2 = int(ceil(bnd.x2)); + prepared->bounds.y2 = int(ceil(bnd.y2)); + prepared->advance_x = int26p6_to_dbl(m_ft_face->glyph->advance.x); + prepared->advance_y = int26p6_to_dbl(m_ft_face->glyph->advance.y); + m_affine.transform(&prepared->advance_x, &prepared->advance_y); + success=true; + } + } + } + break; + + case glyph_ren_agg_mono: + if(error == 0) + { + m_engine.m_rasterizer.reset(); + if(m_engine.m_flag32) + { + m_engine.m_path32.remove_all(); + decompose_ft_outline(m_ft_face->glyph->outline, + m_flip_y, + m_affine, + m_engine.m_path32); + m_engine.m_rasterizer.add_path(m_engine.m_curves32); + } + else + { + m_engine.m_path16.remove_all(); + decompose_ft_outline(m_ft_face->glyph->outline, + m_flip_y, + m_affine, + m_engine.m_path16); + m_engine.m_rasterizer.add_path(m_engine.m_curves16); + } + m_engine.m_scanlines_bin.prepare(); // Remove all + render_scanlines(m_engine.m_rasterizer, m_engine.m_scanline_bin, m_engine.m_scanlines_bin); + prepared->bounds.x1 = m_engine.m_scanlines_bin.min_x(); + prepared->bounds.y1 = m_engine.m_scanlines_bin.min_y(); + prepared->bounds.x2 = m_engine.m_scanlines_bin.max_x() + 1; + prepared->bounds.y2 = m_engine.m_scanlines_bin.max_y() + 1; + prepared->data_size = m_engine.m_scanlines_bin.byte_size(); + prepared->data_type = glyph_data_mono; + prepared->advance_x = int26p6_to_dbl(m_ft_face->glyph->advance.x); + prepared->advance_y = int26p6_to_dbl(m_ft_face->glyph->advance.y); + m_affine.transform(&prepared->advance_x, &prepared->advance_y); + success=true; + } + break; + + + case glyph_ren_agg_gray8: + if(error == 0) + { + m_engine.m_rasterizer.reset(); + if(m_engine.m_flag32) + { + m_engine.m_path32.remove_all(); + decompose_ft_outline(m_ft_face->glyph->outline, + m_flip_y, + m_affine, + m_engine.m_path32); + m_engine.m_rasterizer.add_path(m_engine.m_curves32); + } + else + { + m_engine.m_path16.remove_all(); + decompose_ft_outline(m_ft_face->glyph->outline, + m_flip_y, + m_affine, + m_engine.m_path16); + m_engine.m_rasterizer.add_path(m_engine.m_curves16); + } + m_engine.m_scanlines_aa.prepare(); // Remove all + render_scanlines(m_engine.m_rasterizer, m_engine.m_scanline_aa, m_engine.m_scanlines_aa); + prepared->bounds.x1 = m_engine.m_scanlines_aa.min_x(); + prepared->bounds.y1 = m_engine.m_scanlines_aa.min_y(); + prepared->bounds.x2 = m_engine.m_scanlines_aa.max_x() + 1; + prepared->bounds.y2 = m_engine.m_scanlines_aa.max_y() + 1; + prepared->data_size = m_engine.m_scanlines_aa.byte_size(); + prepared->data_type = glyph_data_gray8; + prepared->advance_x = int26p6_to_dbl(m_ft_face->glyph->advance.x); + prepared->advance_y = int26p6_to_dbl(m_ft_face->glyph->advance.y); + m_affine.transform(&prepared->advance_x, &prepared->advance_y); + success=true; + } + break; + } + } + return success; + } + + //------------------------------------------------------------------------ + void font_engine_freetype_base::loaded_face::write_glyph_to(prepared_glyph *prepared, int8u* data) const + { + if(data && prepared->data_size) + { + switch(prepared->data_type) + { + default: return; + case glyph_data_mono: m_engine.m_scanlines_bin.serialize(data); break; + case glyph_data_gray8: m_engine.m_scanlines_aa.serialize(data); break; + case glyph_data_outline: + if(m_engine.m_flag32) + { + m_engine.m_path32.serialize(data); + } + else + { + m_engine.m_path16.serialize(data); + } + break; + case glyph_data_invalid: break; + } + } + } + + //------------------------------------------------------------------------ + bool font_engine_freetype_base::loaded_face::add_kerning( + unsigned first, unsigned second, double* x, double* y) + { + bool success=false; + if(first && second && FT_HAS_KERNING(m_ft_face)) + { + FT_Vector delta; + int error= FT_Get_Kerning(m_ft_face, first, second, + FT_KERNING_DEFAULT, &delta); + if( error==0 ) + { + double dx = int26p6_to_dbl(delta.x); + double dy = int26p6_to_dbl(delta.y); + if( m_rendering == glyph_ren_outline || + m_rendering == glyph_ren_agg_mono || + m_rendering == glyph_ren_agg_gray8) + { + m_affine.transform_2x2(&dx, &dy); + } + *x += dx; + *y += dy; + } + success=true; + } + return success; + } + + //------------------------------------------------------------------------ + void font_engine_freetype_base::loaded_face::set_face_name() + { + if( !stricmp(m_ft_face->style_name,"Regular") ) + { + std::size_t len=std::strlen(m_ft_face->family_name)+1; + m_face_name=new char[len]; + std::strcpy(m_face_name, m_ft_face->family_name); + } + else + { + std::size_t len=std::strlen(m_ft_face->family_name)+1+std::strlen(m_ft_face->style_name)+1; + m_face_name=new char[len]; + std::sprintf( m_face_name, "%s %s", m_ft_face->family_name, m_ft_face->style_name ); + } + } + + + + + + + + + + //------------------------------------------------------------------------ + font_engine_freetype_base::~font_engine_freetype_base() + { + if(m_library_initialized) FT_Done_FreeType(m_library); + } + + //------------------------------------------------------------------------ + + static FT_Error ft_init_freeType( FT_Library *alibrary, FT_Memory memory ) + { + FT_Error error; + + error = FT_New_Library( memory, alibrary ); + if ( error ) + { }// FT_Done_Memory( memory ); + else + FT_Add_Default_Modules( *alibrary ); + + return error; + } + + font_engine_freetype_base::font_engine_freetype_base( bool flag32, void *ftMemory) + :m_flag32(flag32) + ,m_last_error(0) + ,m_library_initialized(false) + ,m_path16() + ,m_path32() + ,m_curves16(m_path16) + ,m_curves32(m_path32) + ,m_scanline_aa() + ,m_scanline_bin() + ,m_scanlines_aa() + ,m_scanlines_bin() + ,m_rasterizer() + { + m_curves16.approximation_scale(4.0); + m_curves32.approximation_scale(4.0); + m_last_error = ft_init_freeType(&m_library,FT_Memory(ftMemory)); + if(m_last_error == 0) m_library_initialized = true; + } + + //------------------------------------------------------------------------ + font_engine_freetype_base::loaded_face *font_engine_freetype_base::load_face( + const void* buffer, std::size_t bytes) + { + loaded_face *face=0; + if(m_library_initialized) + { + FT_Face ft_face; + int error = FT_New_Memory_Face( + m_library, + (const FT_Byte*)buffer, + bytes, + 0, + &ft_face ); + if( error==0 ) + { + face=create_loaded_face(ft_face); + } + } + return face; + } + //------------------------------------------------------------------------ + font_engine_freetype_base::loaded_face *font_engine_freetype_base::load_face_file( + const char* file_name ) + { + loaded_face *face=0; + if(m_library_initialized) + { + FT_Face ft_face; + int error = FT_New_Face( + m_library, + file_name, + 0, + &ft_face ); + if( error==0 ) + { + face=create_loaded_face(ft_face); + } + } + return face; + } + + //------------------------------------------------------------------------ + font_engine_freetype_base::loaded_face *font_engine_freetype_base::create_loaded_face(FT_Face ft_face) + { + loaded_face *face=new loaded_face( *this, ft_face ); + + return face; + } + + //------------------------------------------------------------------------ + /* + bool font_engine_freetype_base::attach(const char* file_name) + { + if(m_cur_face) + { + m_last_error = FT_Attach_File(m_cur_face, file_name); + return m_last_error == 0; + } + return false; + } + */ +} +} + + diff --git a/font_freetype/agg_font_freetype2.h b/font_freetype/agg_font_freetype2.h new file mode 100644 index 0000000..053915d --- /dev/null +++ b/font_freetype/agg_font_freetype2.h @@ -0,0 +1,331 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// See implementation agg_font_freetype.cpp +// +//---------------------------------------------------------------------------- + +#ifndef AGG_FONT_FREETYPE_INCLUDED +#define AGG_FONT_FREETYPE_INCLUDED + +#include <ft2build.h> +#include FT_FREETYPE_H + + +#include <cstddef> +#include "agg_scanline_storage_aa.h" +#include "agg_scanline_storage_bin.h" +#include "agg_scanline_u.h" +#include "agg_scanline_bin.h" +#include "agg_path_storage_integer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_conv_curve.h" +#include "agg_font_cache_manager.h" +#include "agg_font_cache_manager2.h" +#include "agg_trans_affine.h" + +namespace agg { +namespace fman { + + + //-----------------------------------------------font_engine_freetype_base + class font_engine_freetype_base + { + public: + struct prepared_glyph + { + unsigned glyph_code; + unsigned glyph_index; + unsigned data_size; + glyph_data_type data_type; + rect_i bounds; + double advance_x; + double advance_y; + }; + + class loaded_face + { + public: + loaded_face( font_engine_freetype_base &engine, FT_Face face ) + : m_engine( engine ) + , m_ft_face( face ) + , m_dpi( 0 ) + , m_height( 0 ) + , m_width( 0 ) + , m_rendering( glyph_ren_native_gray8 ) + , m_hinting( false ) + , m_flip_y( true ) + , m_char_map( FT_ENCODING_NONE ) + { + set_face_name(); + } + + ~loaded_face() + { + FT_Done_Face( m_ft_face); + delete[] m_face_name; + } + + unsigned num_faces() const + { + return m_ft_face->num_faces; + } + + const char *name() const + { + return m_face_name; + } + + unsigned resolution() const + { + return m_dpi; + } + + double height() const + { + return m_height; + } + + double width() const + { + return m_width; + } + + double ascent() const + { + return m_ft_face->ascender*height()/m_ft_face->height; + } + + double descent() const + { + return m_ft_face->descender*height()/m_ft_face->height; + } + + double ascent_b() const + { + return m_ft_face->bbox.yMax*height()/m_ft_face->height; + } + + double descent_b() const + { + return m_ft_face->bbox.yMin*height()/m_ft_face->height; + } + + bool hinting() const + { + return m_hinting; + } + + bool flip_y() const + { + return m_flip_y; + } + + const trans_affine &transform() const + { + return m_affine; + } + + FT_Encoding char_map() const + { + return m_char_map; + } + + void set_hinting( bool h ) + { + m_hinting=h; + } + + /* + void set_resolution(int dpi) + { m_dpi=dpi; update_char_size(); } + void set_height( double h ) + { m_height=int(h*64.0); update_char_size(); } + void set_width( double w ) + { m_width=int(w*64.0); update_char_size(); } + void set_flip_y(bool f) + { m_flip_y=f; } + void set_transform(const trans_affine& affine) + { m_affine=affine; } + int set_char_map(FT_Encoding char_map) + { FT_Select_Charmap(m_ft_face, char_map); } + */ + void select_instance( + double height, + double width, + bool hinting, + glyph_rendering rendering ) + { + rendering=capable_rendering(rendering); + + if( m_height != height || + m_width != width || + m_hinting != hinting || + m_rendering != rendering ) + { + m_height = height; + m_width = width; + m_hinting = hinting; + m_rendering = rendering; + update_char_size(); + } + } + + glyph_rendering capable_rendering( glyph_rendering rendering ) const + { + switch(rendering) + { + case glyph_ren_native_mono: + case glyph_ren_native_gray8: + break; + + case glyph_ren_outline: + if(!FT_IS_SCALABLE(m_ft_face)) + rendering = glyph_ren_native_gray8; + break; + + case glyph_ren_agg_mono: + if(!FT_IS_SCALABLE(m_ft_face)) + rendering = glyph_ren_native_mono; + break; + + case glyph_ren_agg_gray8: + if(!FT_IS_SCALABLE(m_ft_face)) + rendering = glyph_ren_native_gray8; + break; + }; + return rendering; + } + + void update_char_size() + { + if( m_dpi ) + FT_Set_Char_Size( m_ft_face, int(m_width*64), int(m_height*64), m_dpi, m_dpi ); + else + FT_Set_Pixel_Sizes( m_ft_face, int(m_width), int(m_height) ); + } + + bool prepare_glyph(unsigned glyph_code, prepared_glyph *prepared ) const; + bool add_kerning(unsigned first, unsigned second, double* x, double* y); + void write_glyph_to(prepared_glyph *prepared, int8u* data) const; + + private: + void set_face_name(); + + loaded_face(const loaded_face &); + loaded_face &operator=(const loaded_face &); + + private: + font_engine_freetype_base &m_engine; + FT_Face m_ft_face; + char *m_face_name; + int m_dpi; + double m_height; + double m_width; + glyph_rendering m_rendering; + bool m_hinting; + bool m_flip_y; + trans_affine m_affine; + FT_Encoding m_char_map; + }; + + //-------------------------------------------------------------------- + typedef serialized_scanlines_adaptor_aa<int8u> gray8_adaptor_type; + typedef serialized_scanlines_adaptor_bin mono_adaptor_type; + typedef scanline_storage_aa8 scanlines_aa_type; + typedef scanline_storage_bin scanlines_bin_type; + + //-------------------------------------------------------------------- + ~font_engine_freetype_base(); + font_engine_freetype_base(bool flag32, void *ftMemory=0); + + // Load families and faces + //-------------------------------------------------------------------- + loaded_face *load_face(const void* buffer, std::size_t bytes); + loaded_face *load_face_file(const char* file_name); + loaded_face *create_loaded_face(FT_Face ft_face); // internal + void unload_face(loaded_face *face); + + // Set Gamma + //-------------------------------------------------------------------- + template<class GammaF> void gamma(const GammaF& f) + { + m_rasterizer.gamma(f); + } + + private: + font_engine_freetype_base(const font_engine_freetype_base&); + const font_engine_freetype_base& operator = (const font_engine_freetype_base&); + + bool m_flag32; + int m_last_error; + bool m_library_initialized; + FT_Library m_library; // handle to library + + path_storage_integer<int16, 6> m_path16; + path_storage_integer<int32, 6> m_path32; + conv_curve<path_storage_integer<int16, 6> > m_curves16; + conv_curve<path_storage_integer<int32, 6> > m_curves32; + scanline_u8 m_scanline_aa; + scanline_bin m_scanline_bin; + scanlines_aa_type m_scanlines_aa; + scanlines_bin_type m_scanlines_bin; + rasterizer_scanline_aa<> m_rasterizer; + }; + + + + + //------------------------------------------------font_engine_freetype_int16 + // This class uses values of type int16 (10.6 format) for the vector cache. + // The vector cache is compact, but when rendering glyphs of height + // more that 200 there integer overflow can occur. + // + class font_engine_freetype_int16 : public font_engine_freetype_base + { + public: + typedef serialized_integer_path_adaptor<int16, 6> path_adaptor_type; + typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type; + typedef font_engine_freetype_base::mono_adaptor_type mono_adaptor_type; + typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type; + typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type; + + font_engine_freetype_int16(void *ftMemory = 0) : + font_engine_freetype_base(false, ftMemory) {} + }; + + //------------------------------------------------font_engine_freetype_int32 + // This class uses values of type int32 (26.6 format) for the vector cache. + // The vector cache is twice larger than in font_engine_freetype_int16, + // but it allows you to render glyphs of very large sizes. + // + class font_engine_freetype_int32 : public font_engine_freetype_base + { + public: + typedef serialized_integer_path_adaptor<int32, 6> path_adaptor_type; + typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type; + typedef font_engine_freetype_base::mono_adaptor_type mono_adaptor_type; + typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type; + typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type; + + font_engine_freetype_int32(void *ftMemory = 0) : + font_engine_freetype_base(true, ftMemory) {} + }; + + +} +} + +#endif diff --git a/font_win32_tt/Makefile.am b/font_win32_tt/Makefile.am new file mode 100644 index 0000000..f03381c --- /dev/null +++ b/font_win32_tt/Makefile.am @@ -0,0 +1,13 @@ +## this needs more work, and is intended to work in a unix cross +## compilation toolchain, or in something like msys + +if ENABLE_WIN32_TT +aggincludedir = $(includedir)/agg2 +agginclude_HEADERS = agg_font_win32_tt.h +lib_LTLIBRARIES = libaggfontwin32tt.la + +libaggfontwin32tt_la_LDFLAGS = -no-undefined -version-info @AGG_LIB_VERSION@ @WINDOWS_LIBS@ ../src/libagg.la +libaggfontwin32tt_la_SOURCES = agg_font_win32_tt.cpp +libaggfontwin32tt_la_CXXFLAGS = -I$(top_srcdir)/include @WINDOWS_CFLAGS@ +endif + diff --git a/font_win32_tt/agg_font_win32_tt.cpp b/font_win32_tt/agg_font_win32_tt.cpp new file mode 100644 index 0000000..b23bb5e --- /dev/null +++ b/font_win32_tt/agg_font_win32_tt.cpp @@ -0,0 +1,938 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include <cstdio> +#include <cstring> +#include "agg_font_win32_tt.h" +#include "agg_bitset_iterator.h" +#include "agg_renderer_scanline.h" + +#ifdef AGG_WIN9X_COMPLIANT +#define GetGlyphOutlineX GetGlyphOutline +#else +#define GetGlyphOutlineX GetGlyphOutlineW +#endif + +namespace agg +{ + + //------------------------------------------------------------------------------ + // + // This code implements the AUTODIN II polynomial + // The variable corresponding to the macro argument "crc" should + // be an unsigned long. + // Oroginal code by Spencer Garrett <srg@quick.com> + // + + // generated using the AUTODIN II polynomial + // x^32 + x^26 + x^23 + x^22 + x^16 + + // x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 + // + //------------------------------------------------------------------------------ + + static const unsigned crc32tab[256] = + { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, + }; + + //------------------------------------------------------------------------------ + static unsigned calc_crc32(const unsigned char* buf, unsigned size) + { + unsigned crc = (unsigned)~0; + const unsigned char* p; + unsigned len = 0; + unsigned nr = size; + + for (len += nr, p = buf; nr--; ++p) + { + crc = (crc >> 8) ^ crc32tab[(crc ^ *p) & 0xff]; + } + return ~crc; + } + + //------------------------------------------------------------------------ + static inline FIXED dbl_to_fx(double d) + { + int l; + l = int(d * 65536.0); + return *(FIXED*)&l; + } + + //------------------------------------------------------------------------ + static inline int dbl_to_plain_fx(double d) + { + return int(d * 65536.0); + } + + //------------------------------------------------------------------------ + static inline FIXED negate_fx(const FIXED& fx) + { + int l = -(*(int*)(&fx)); + return *(FIXED*)&l; + } + + //------------------------------------------------------------------------ + static inline double fx_to_dbl(const FIXED& p) + { + return double(p.value) + double(p.fract) * (1.0 / 65536.0); + } + + //------------------------------------------------------------------------ + static inline int fx_to_plain_int(const FIXED& fx) + { + return *(int*)(&fx); + } + + //------------------------------------------------------------------------ + static inline int fx_to_int26p6(const FIXED& p) + { + return (int(p.value) << 6) + (int(p.fract) >> 10); + } + + //------------------------------------------------------------------------ + static inline int dbl_to_int26p6(double p) + { + return int(p * 64.0 + 0.5); + } + + //------------------------------------------------------------------------ + template<class Scanline, class ScanlineStorage> + void decompose_win32_glyph_bitmap_mono(const char* gbuf, + int w, int h, + int x, int y, + bool flip_y, + Scanline& sl, + ScanlineStorage& storage) + { + int i; + int pitch = ((w + 31) >> 5) << 2; + const int8u* buf = (const int8u*)gbuf; + sl.reset(x, x + w); + storage.prepare(); + if(flip_y) + { + buf += pitch * (h - 1); + y += h; + pitch = -pitch; + } + for(i = 0; i < h; i++) + { + sl.reset_spans(); + bitset_iterator bits(buf, 0); + int j; + for(j = 0; j < w; j++) + { + if(bits.bit()) sl.add_cell(x + j, cover_full); + ++bits; + } + buf += pitch; + if(sl.num_spans()) + { + sl.finalize(y - i - 1); + storage.render(sl); + } + } + } + + + + //------------------------------------------------------------------------ + template<class Rasterizer, class Scanline, class ScanlineStorage> + void decompose_win32_glyph_bitmap_gray8(const char* gbuf, + int w, int h, + int x, int y, + bool flip_y, + Rasterizer& ras, + Scanline& sl, + ScanlineStorage& storage) + { + int i, j; + int pitch = ((w + 3) >> 2) << 2; + const int8u* buf = (const int8u*)gbuf; + sl.reset(x, x + w); + storage.prepare(); + if(flip_y) + { + buf += pitch * (h - 1); + y += h; + pitch = -pitch; + } + for(i = 0; i < h; i++) + { + sl.reset_spans(); + const int8u* p = buf; + for(j = 0; j < w; j++) + { + if(*p) + { + unsigned v = *p; + if(v == 64) v = 255; + else v <<= 2; + sl.add_cell(x + j, ras.apply_gamma(v)); + } + ++p; + } + buf += pitch; + if(sl.num_spans()) + { + sl.finalize(y - i - 1); + storage.render(sl); + } + } + } + + + + //------------------------------------------------------------------------ + template<class PathStorage> + bool decompose_win32_glyph_outline(const char* gbuf, + unsigned total_size, + bool flip_y, + const trans_affine& mtx, + PathStorage& path) + { + const char* cur_glyph = gbuf; + const char* end_glyph = gbuf + total_size; + double x, y; + typedef typename PathStorage::value_type value_type; + + while(cur_glyph < end_glyph) + { + const TTPOLYGONHEADER* th = (TTPOLYGONHEADER*)cur_glyph; + + const char* end_poly = cur_glyph + th->cb; + const char* cur_poly = cur_glyph + sizeof(TTPOLYGONHEADER); + + x = fx_to_dbl(th->pfxStart.x); + y = fx_to_dbl(th->pfxStart.y); + if(flip_y) y = -y; + mtx.transform(&x, &y); + path.move_to(value_type(dbl_to_int26p6(x)), + value_type(dbl_to_int26p6(y))); + + while(cur_poly < end_poly) + { + const TTPOLYCURVE* pc = (const TTPOLYCURVE*)cur_poly; + + if (pc->wType == TT_PRIM_LINE) + { + int i; + for (i = 0; i < pc->cpfx; i++) + { + x = fx_to_dbl(pc->apfx[i].x); + y = fx_to_dbl(pc->apfx[i].y); + if(flip_y) y = -y; + mtx.transform(&x, &y); + path.line_to(value_type(dbl_to_int26p6(x)), + value_type(dbl_to_int26p6(y))); + } + } + + if (pc->wType == TT_PRIM_QSPLINE) + { + int u; + for (u = 0; u < pc->cpfx - 1; u++) // Walk through points in spline + { + POINTFX pnt_b = pc->apfx[u]; // B is always the current point + POINTFX pnt_c = pc->apfx[u+1]; + + if (u < pc->cpfx - 2) // If not on last spline, compute C + { + // midpoint (x,y) + *(int*)&pnt_c.x = (*(int*)&pnt_b.x + *(int*)&pnt_c.x) / 2; + *(int*)&pnt_c.y = (*(int*)&pnt_b.y + *(int*)&pnt_c.y) / 2; + } + + double x2, y2; + x = fx_to_dbl(pnt_b.x); + y = fx_to_dbl(pnt_b.y); + x2 = fx_to_dbl(pnt_c.x); + y2 = fx_to_dbl(pnt_c.y); + if(flip_y) { y = -y; y2 = -y2; } + mtx.transform(&x, &y); + mtx.transform(&x2, &y2); + path.curve3(value_type(dbl_to_int26p6(x)), + value_type(dbl_to_int26p6(y)), + value_type(dbl_to_int26p6(x2)), + value_type(dbl_to_int26p6(y2))); + } + } + cur_poly += sizeof(WORD) * 2 + sizeof(POINTFX) * pc->cpfx; + } + cur_glyph += th->cb; + } + return true; + } + + + + + //------------------------------------------------------------------------ + font_engine_win32_tt_base::~font_engine_win32_tt_base() + { + delete [] m_kerning_pairs; + delete [] m_gbuf; + delete [] m_signature; + delete [] m_typeface; + if(m_dc && m_old_font) ::SelectObject(m_dc, m_old_font); + unsigned i; + for(i = 0; i < m_num_fonts; ++i) + { + delete [] m_font_names[i]; + ::DeleteObject(m_fonts[i]); + } + delete [] m_font_names; + delete [] m_fonts; + } + + + + //------------------------------------------------------------------------ + font_engine_win32_tt_base::font_engine_win32_tt_base(bool flag32, + HDC dc, + unsigned max_fonts) : + m_flag32(flag32), + m_dc(dc), + m_old_font(m_dc ? (HFONT)::GetCurrentObject(m_dc, OBJ_FONT) : 0), + m_fonts(new HFONT [max_fonts]), + m_num_fonts(0), + m_max_fonts(max_fonts), + m_font_names(new char* [max_fonts]), + m_cur_font(0), + + m_change_stamp(0), + m_typeface(new char [256-16]), + m_typeface_len(256-16-1), + m_signature(new char [256+256-16]), + m_height(0), + m_width(0), + m_weight(FW_REGULAR), + m_italic(false), + m_char_set(DEFAULT_CHARSET), + m_pitch_and_family(FF_DONTCARE), + m_hinting(true), + m_flip_y(false), + m_font_created(false), + m_resolution(0), + m_glyph_rendering(glyph_ren_native_gray8), + m_glyph_index(0), + m_data_size(0), + m_data_type(glyph_data_invalid), + m_bounds(1,1,0,0), + m_advance_x(0.0), + m_advance_y(0.0), + m_gbuf(new char [buf_size]), + m_kerning_pairs(0), + m_num_kerning_pairs(0), + m_max_kerning_pairs(0), + + m_path16(), + m_path32(), + m_curves16(m_path16), + m_curves32(m_path32), + m_scanline_aa(), + m_scanline_bin(), + m_scanlines_aa(), + m_scanlines_bin(), + m_rasterizer() + { + m_curves16.approximation_scale(4.0); + m_curves32.approximation_scale(4.0); + std::memset(&m_matrix, 0, sizeof(m_matrix)); + m_matrix.eM11.value = 1; + m_matrix.eM22.value = 1; + } + + + + //------------------------------------------------------------------------ + int font_engine_win32_tt_base::find_font(const char* name) const + { + unsigned i; + for(i = 0; i < m_num_fonts; ++i) + { + if(std::strcmp(name, m_font_names[i]) == 0) return i; + } + return -1; + } + + //------------------------------------------------------------------------ + bool font_engine_win32_tt_base::create_font(const char* typeface_, + glyph_rendering ren_type) + { + if(m_dc) + { + unsigned len = strlen(typeface_); + if(len > m_typeface_len) + { + delete [] m_signature; + delete [] m_typeface; + m_typeface = new char [len + 32]; + m_signature = new char [len + 32 + 256]; + m_typeface_len = len + 32 - 1; + } + + strcpy(m_typeface, typeface_); + + int h = m_height; + int w = m_width; + + if(m_resolution) + { + h = ::MulDiv(m_height, m_resolution, 72); + w = ::MulDiv(m_width, m_resolution, 72); + } + + m_glyph_rendering = ren_type; + update_signature(); + int idx = find_font(m_signature); + if(idx >= 0) + { + m_cur_font = m_fonts[idx]; + ::SelectObject(m_dc, m_cur_font); + m_num_kerning_pairs = 0; + return true; + } + else + { + m_cur_font = ::CreateFont(-h, // height of font + w, // average character width + 0, // angle of escapement + 0, // base-line orientation angle + m_weight, // font weight + m_italic, // italic attribute option + 0, // underline attribute option + 0, // strikeout attribute option + m_char_set, // character set identifier + OUT_DEFAULT_PRECIS, // output precision + CLIP_DEFAULT_PRECIS, // clipping precision + ANTIALIASED_QUALITY, // output quality + m_pitch_and_family, // pitch and family + m_typeface); // typeface name + if(m_cur_font) + { + if(m_num_fonts >= m_max_fonts) + { + delete [] m_font_names[0]; + if(m_old_font) ::SelectObject(m_dc, m_old_font); + ::DeleteObject(m_fonts[0]); + std::memcpy(m_fonts, + m_fonts + 1, + (m_max_fonts - 1) * sizeof(HFONT)); + std::memcpy(m_font_names, + m_font_names + 1, + (m_max_fonts - 1) * sizeof(char*)); + m_num_fonts = m_max_fonts - 1; + } + + update_signature(); + m_font_names[m_num_fonts] = new char[std::strlen(m_signature) + 1]; + std::strcpy(m_font_names[m_num_fonts], m_signature); + m_fonts[m_num_fonts] = m_cur_font; + ++m_num_fonts; + ::SelectObject(m_dc, m_cur_font); + m_num_kerning_pairs = 0; + return true; + } + } + } + return false; + } + + + + + + //------------------------------------------------------------------------ + bool font_engine_win32_tt_base::create_font(const char* typeface_, + glyph_rendering ren_type, + double height_, + double width_, + int weight_, + bool italic_, + DWORD char_set_, + DWORD pitch_and_family_) + { + height(height_); + width(width_); + weight(weight_); + italic(italic_); + char_set(char_set_); + pitch_and_family(pitch_and_family_); + return create_font(typeface_, ren_type); + } + + + + + //------------------------------------------------------------------------ + void font_engine_win32_tt_base::update_signature() + { + m_signature[0] = 0; + if(m_dc && m_cur_font) + { + unsigned gamma_hash = 0; + if(m_glyph_rendering == glyph_ren_native_gray8 || + m_glyph_rendering == glyph_ren_agg_mono || + m_glyph_rendering == glyph_ren_agg_gray8) + { + unsigned char gamma_table[rasterizer_scanline_aa<>::aa_scale]; + unsigned i; + for(i = 0; i < rasterizer_scanline_aa<>::aa_scale; ++i) + { + gamma_table[i] = m_rasterizer.apply_gamma(i); + } + gamma_hash = calc_crc32(gamma_table, sizeof(gamma_table)); + } + + sprintf(m_signature, + "%s,%u,%d,%d:%dx%d,%d,%d,%d,%d,%d,%08X", + m_typeface, + m_char_set, + int(m_glyph_rendering), + m_resolution, + m_height, + m_width, + m_weight, + int(m_italic), + int(m_hinting), + int(m_flip_y), + int(m_pitch_and_family), + gamma_hash); + + if(m_glyph_rendering == glyph_ren_outline || + m_glyph_rendering == glyph_ren_agg_mono || + m_glyph_rendering == glyph_ren_agg_gray8) + { + double mtx[6]; + char buf[100]; + m_affine.store_to(mtx); + std::sprintf(buf, ",%08X%08X%08X%08X%08X%08X", + dbl_to_plain_fx(mtx[0]), + dbl_to_plain_fx(mtx[1]), + dbl_to_plain_fx(mtx[2]), + dbl_to_plain_fx(mtx[3]), + dbl_to_plain_fx(mtx[4]), + dbl_to_plain_fx(mtx[5])); + std::strcat(m_signature, buf); + } + ++m_change_stamp; + } + } + + + + //------------------------------------------------------------------------ + bool font_engine_win32_tt_base::prepare_glyph(unsigned glyph_code) + { + if(m_dc && m_cur_font) + { + int format = GGO_BITMAP; + + switch(m_glyph_rendering) + { + case glyph_ren_native_gray8: + format = GGO_GRAY8_BITMAP; + break; + + case glyph_ren_outline: + case glyph_ren_agg_mono: + case glyph_ren_agg_gray8: + format = GGO_NATIVE; + break; + } + +#ifndef GGO_UNHINTED // For compatibility with old SDKs. +#define GGO_UNHINTED 0x0100 +#endif + if(!m_hinting) format |= GGO_UNHINTED; + + GLYPHMETRICS gm; + int total_size = GetGlyphOutlineX(m_dc, + glyph_code, + format, + &gm, + buf_size, + (void*)m_gbuf, + &m_matrix); + + if(total_size < 0) + { + // GetGlyphOutline() fails when being called for + // GGO_GRAY8_BITMAP and white space (stupid Microsoft). + // It doesn't even initialize the glyph metrics + // structure. So, we have to query the metrics + // separately (basically we need gmCellIncX). + int total_size = GetGlyphOutlineX(m_dc, + glyph_code, + GGO_METRICS, + &gm, + buf_size, + (void*)m_gbuf, + &m_matrix); + + if(total_size < 0) return false; + gm.gmBlackBoxX = gm.gmBlackBoxY = 0; + total_size = 0; + } + + m_glyph_index = glyph_code; + m_advance_x = gm.gmCellIncX; + m_advance_y = -gm.gmCellIncY; + + switch(m_glyph_rendering) + { + case glyph_ren_native_mono: + decompose_win32_glyph_bitmap_mono(m_gbuf, + gm.gmBlackBoxX, + gm.gmBlackBoxY, + gm.gmptGlyphOrigin.x, + m_flip_y ? -gm.gmptGlyphOrigin.y : + gm.gmptGlyphOrigin.y, + m_flip_y, + m_scanline_bin, + m_scanlines_bin); + m_bounds.x1 = m_scanlines_bin.min_x(); + m_bounds.y1 = m_scanlines_bin.min_y(); + m_bounds.x2 = m_scanlines_bin.max_x() + 1; + m_bounds.y2 = m_scanlines_bin.max_y() + 1; + m_data_size = m_scanlines_bin.byte_size(); + m_data_type = glyph_data_mono; + return true; + + case glyph_ren_native_gray8: + decompose_win32_glyph_bitmap_gray8(m_gbuf, + gm.gmBlackBoxX, + gm.gmBlackBoxY, + gm.gmptGlyphOrigin.x, + m_flip_y ? -gm.gmptGlyphOrigin.y : + gm.gmptGlyphOrigin.y, + m_flip_y, + m_rasterizer, + m_scanline_aa, + m_scanlines_aa); + m_bounds.x1 = m_scanlines_aa.min_x(); + m_bounds.y1 = m_scanlines_aa.min_y(); + m_bounds.x2 = m_scanlines_aa.max_x() + 1; + m_bounds.y2 = m_scanlines_aa.max_y() + 1; + m_data_size = m_scanlines_aa.byte_size(); + m_data_type = glyph_data_gray8; + return true; + + case glyph_ren_outline: + m_affine.transform(&m_advance_x, &m_advance_y); + if(m_flag32) + { + m_path32.remove_all(); + if(decompose_win32_glyph_outline(m_gbuf, + total_size, + m_flip_y, + m_affine, + m_path32)) + { + rect_d bnd = m_path32.bounding_rect(); + m_data_size = m_path32.byte_size(); + m_data_type = glyph_data_outline; + m_bounds.x1 = int(floor(bnd.x1)); + m_bounds.y1 = int(floor(bnd.y1)); + m_bounds.x2 = int(ceil(bnd.x2)); + m_bounds.y2 = int(ceil(bnd.y2)); + return true; + } + } + else + { + m_path16.remove_all(); + if(decompose_win32_glyph_outline(m_gbuf, + total_size, + m_flip_y, + m_affine, + m_path16)) + { + rect_d bnd = m_path16.bounding_rect(); + m_data_size = m_path16.byte_size(); + m_data_type = glyph_data_outline; + m_bounds.x1 = int(floor(bnd.x1)); + m_bounds.y1 = int(floor(bnd.y1)); + m_bounds.x2 = int(ceil(bnd.x2)); + m_bounds.y2 = int(ceil(bnd.y2)); + return true; + } + } + break; + + case glyph_ren_agg_mono: + m_rasterizer.reset(); + m_affine.transform(&m_advance_x, &m_advance_y); + if(m_flag32) + { + m_path32.remove_all(); + decompose_win32_glyph_outline(m_gbuf, + total_size, + m_flip_y, + m_affine, + m_path32); + m_rasterizer.add_path(m_curves32); + } + else + { + m_path16.remove_all(); + decompose_win32_glyph_outline(m_gbuf, + total_size, + m_flip_y, + m_affine, + m_path16); + m_rasterizer.add_path(m_curves16); + } + m_scanlines_bin.prepare(); // Remove all + render_scanlines(m_rasterizer, m_scanline_bin, m_scanlines_bin); + m_bounds.x1 = m_scanlines_bin.min_x(); + m_bounds.y1 = m_scanlines_bin.min_y(); + m_bounds.x2 = m_scanlines_bin.max_x() + 1; + m_bounds.y2 = m_scanlines_bin.max_y() + 1; + m_data_size = m_scanlines_bin.byte_size(); + m_data_type = glyph_data_mono; + return true; + + case glyph_ren_agg_gray8: + m_rasterizer.reset(); + m_affine.transform(&m_advance_x, &m_advance_y); + if(m_flag32) + { + m_path32.remove_all(); + decompose_win32_glyph_outline(m_gbuf, + total_size, + m_flip_y, + m_affine, + m_path32); + m_rasterizer.add_path(m_curves32); + } + else + { + m_path16.remove_all(); + decompose_win32_glyph_outline(m_gbuf, + total_size, + m_flip_y, + m_affine, + m_path16); + m_rasterizer.add_path(m_curves16); + } + m_scanlines_aa.prepare(); // Remove all + render_scanlines(m_rasterizer, m_scanline_aa, m_scanlines_aa); + m_bounds.x1 = m_scanlines_aa.min_x(); + m_bounds.y1 = m_scanlines_aa.min_y(); + m_bounds.x2 = m_scanlines_aa.max_x() + 1; + m_bounds.y2 = m_scanlines_aa.max_y() + 1; + m_data_size = m_scanlines_aa.byte_size(); + m_data_type = glyph_data_gray8; + return true; + } + } + return false; + } + + + + //------------------------------------------------------------------------ + void font_engine_win32_tt_base::write_glyph_to(int8u* data) const + { + if(data && m_data_size) + { + switch(m_data_type) + { + case glyph_data_mono: m_scanlines_bin.serialize(data); break; + case glyph_data_gray8: m_scanlines_aa.serialize(data); break; + case glyph_data_outline: + if(m_flag32) + { + m_path32.serialize(data); + } + else + { + m_path16.serialize(data); + } + break; + } + } + } + + + + //------------------------------------------------------------------------ + static bool pair_less(const KERNINGPAIR& v1, const KERNINGPAIR& v2) + { + if(v1.wFirst != v2.wFirst) return v1.wFirst < v2.wFirst; + return v1.wSecond < v2.wSecond; + } + + + //------------------------------------------------------------------------ + void font_engine_win32_tt_base::sort_kerning_pairs() + { + pod_array_adaptor<KERNINGPAIR> pairs(m_kerning_pairs, m_num_kerning_pairs); + quick_sort(pairs, pair_less); + } + + + + //------------------------------------------------------------------------ + void font_engine_win32_tt_base::load_kerning_pairs() + { + if(m_dc && m_cur_font) + { + if(m_kerning_pairs == 0) + { + m_kerning_pairs = new KERNINGPAIR [16384-16]; + m_max_kerning_pairs = 16384-16; + } + m_num_kerning_pairs = ::GetKerningPairs(m_dc, + m_max_kerning_pairs, + m_kerning_pairs); + + if(m_num_kerning_pairs) + { + // Check to see if the kerning pairs are sorted and + // sort them if they are not. + //---------------- + unsigned i; + for(i = 1; i < m_num_kerning_pairs; ++i) + { + if(!pair_less(m_kerning_pairs[i - 1], m_kerning_pairs[i])) + { + sort_kerning_pairs(); + break; + } + } + } + } + } + + + //------------------------------------------------------------------------ + bool font_engine_win32_tt_base::add_kerning(unsigned first, unsigned second, + double* x, double* y) + { + if(m_dc && m_cur_font) + { + if(m_num_kerning_pairs == 0) + { + load_kerning_pairs(); + } + + int end = m_num_kerning_pairs - 1; + int beg = 0; + KERNINGPAIR t; + t.wFirst = (WORD)first; + t.wSecond = (WORD)second; + while(beg <= end) + { + int mid = (end + beg) / 2; + if(m_kerning_pairs[mid].wFirst == t.wFirst && + m_kerning_pairs[mid].wSecond == t.wSecond) + { + double dx = m_kerning_pairs[mid].iKernAmount; + double dy = 0.0; + if(m_glyph_rendering == glyph_ren_outline || + m_glyph_rendering == glyph_ren_agg_mono || + m_glyph_rendering == glyph_ren_agg_gray8) + { + m_affine.transform_2x2(&dx, &dy); + } + *x += dx; + *y += dy; + return true; + } + else + if(pair_less(t, m_kerning_pairs[mid])) + { + end = mid - 1; + } + else + { + beg = mid + 1; + } + } + return false; + } + return false; + } + + + +} + diff --git a/font_win32_tt/agg_font_win32_tt.h b/font_win32_tt/agg_font_win32_tt.h new file mode 100644 index 0000000..ad030ef --- /dev/null +++ b/font_win32_tt/agg_font_win32_tt.h @@ -0,0 +1,214 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_FONT_WIN32_TT_INCLUDED +#define AGG_FONT_WIN32_TT_INCLUDED + +#include <windows.h> +#include "agg_scanline_storage_aa.h" +#include "agg_scanline_storage_bin.h" +#include "agg_scanline_u.h" +#include "agg_scanline_bin.h" +#include "agg_path_storage_integer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_conv_curve.h" +#include "agg_trans_affine.h" +#include "agg_font_cache_manager.h" + +namespace agg +{ + + //-----------------------------------------------font_engine_win32_tt_base + class font_engine_win32_tt_base + { + enum { buf_size = 32768-32 }; + + public: + //-------------------------------------------------------------------- + typedef serialized_scanlines_adaptor_aa<int8u> gray8_adaptor_type; + typedef serialized_scanlines_adaptor_bin mono_adaptor_type; + typedef scanline_storage_aa8 scanlines_aa_type; + typedef scanline_storage_bin scanlines_bin_type; + + //-------------------------------------------------------------------- + ~font_engine_win32_tt_base(); + font_engine_win32_tt_base(bool flag32, HDC dc, unsigned max_fonts = 32); + + // Set font parameters + //-------------------------------------------------------------------- + void resolution(unsigned dpi) { m_resolution = unsigned(dpi); } + void height(double h) { m_height = unsigned(h); } + void width(double w) { m_width = unsigned(w); } + void weight(int w) { m_weight = w; } + void italic(bool it) { m_italic = it; } + void char_set(DWORD c) { m_char_set = c; } + void pitch_and_family(DWORD p){ m_pitch_and_family = p; } + void flip_y(bool flip) { m_flip_y = flip; } + void hinting(bool h) { m_hinting = h; } + bool create_font(const char* typeface_, glyph_rendering ren_type); + + bool create_font(const char* typeface_, + glyph_rendering ren_type, + double height_, + double width_=0.0, + int weight_=FW_REGULAR, + bool italic_=false, + DWORD char_set_=ANSI_CHARSET, + DWORD pitch_and_family_=FF_DONTCARE); + + // Set Gamma + //-------------------------------------------------------------------- + template<class GammaF> void gamma(const GammaF& f) + { + m_rasterizer.gamma(f); + } + + //-------------------------------------------------------------------- + void transform(const agg::trans_affine& mtx) + { + m_affine = mtx; + } + + // Accessors + //-------------------------------------------------------------------- + unsigned resolution() const { return m_resolution; } + const char* typeface() const { return m_typeface; } + double height() const { return m_height; } + double width() const { return m_width; } + int weight() const { return m_weight; } + bool italic() const { return m_italic; } + DWORD char_set() const { return m_char_set; } + DWORD pitch_and_family() const { return m_pitch_and_family; } + bool hinting() const { return m_hinting; } + bool flip_y() const { return m_flip_y; } + + + // Interface mandatory to implement for font_cache_manager + //-------------------------------------------------------------------- + const char* font_signature() const { return m_signature; } + int change_stamp() const { return m_change_stamp; } + + bool prepare_glyph(unsigned glyph_code); + unsigned glyph_index() const { return m_glyph_index; } + unsigned data_size() const { return m_data_size; } + glyph_data_type data_type() const { return m_data_type; } + const rect_i& bounds() const { return m_bounds; } + double advance_x() const { return m_advance_x; } + double advance_y() const { return m_advance_y; } + void write_glyph_to(int8u* data) const; + bool add_kerning(unsigned first, unsigned second, + double* x, double* y); + + private: + font_engine_win32_tt_base(const font_engine_win32_tt_base&); + const font_engine_win32_tt_base& operator = (const font_engine_win32_tt_base&); + + void update_signature(); + void load_kerning_pairs(); + void sort_kerning_pairs(); + int find_font(const char* name) const; + + bool m_flag32; + HDC m_dc; + HFONT m_old_font; + HFONT* m_fonts; + unsigned m_num_fonts; + unsigned m_max_fonts; + char** m_font_names; + HFONT m_cur_font; + + int m_change_stamp; + char* m_typeface; + unsigned m_typeface_len; + char* m_signature; + unsigned m_height; + unsigned m_width; + int m_weight; + bool m_italic; + DWORD m_char_set; + DWORD m_pitch_and_family; + bool m_hinting; + bool m_flip_y; + + bool m_font_created; + unsigned m_resolution; + glyph_rendering m_glyph_rendering; + unsigned m_glyph_index; + unsigned m_data_size; + glyph_data_type m_data_type; + rect_i m_bounds; + double m_advance_x; + double m_advance_y; + MAT2 m_matrix; + char* m_gbuf; + KERNINGPAIR* m_kerning_pairs; + unsigned m_num_kerning_pairs; + unsigned m_max_kerning_pairs; + trans_affine m_affine; + + path_storage_integer<int16, 6> m_path16; + path_storage_integer<int32, 6> m_path32; + conv_curve<path_storage_integer<int16, 6> > m_curves16; + conv_curve<path_storage_integer<int32, 6> > m_curves32; + scanline_u8 m_scanline_aa; + scanline_bin m_scanline_bin; + scanlines_aa_type m_scanlines_aa; + scanlines_bin_type m_scanlines_bin; + rasterizer_scanline_aa<> m_rasterizer; + }; + + + + + //------------------------------------------------font_engine_win32_tt_int16 + // This class uses values of type int16 (10.6 format) for the vector cache. + // The vector cache is compact, but when rendering glyphs of height + // more that 200 there integer overflow can occur. + // + class font_engine_win32_tt_int16 : public font_engine_win32_tt_base + { + public: + typedef serialized_integer_path_adaptor<int16, 6> path_adaptor_type; + typedef font_engine_win32_tt_base::gray8_adaptor_type gray8_adaptor_type; + typedef font_engine_win32_tt_base::mono_adaptor_type mono_adaptor_type; + typedef font_engine_win32_tt_base::scanlines_aa_type scanlines_aa_type; + typedef font_engine_win32_tt_base::scanlines_bin_type scanlines_bin_type; + + font_engine_win32_tt_int16(HDC dc, unsigned max_fonts = 32) : + font_engine_win32_tt_base(false, dc, max_fonts) {} + }; + + //------------------------------------------------font_engine_win32_tt_int32 + // This class uses values of type int32 (26.6 format) for the vector cache. + // The vector cache is twice larger than in font_engine_win32_tt_int16, + // but it allows you to render glyphs of very large sizes. + // + class font_engine_win32_tt_int32 : public font_engine_win32_tt_base + { + public: + typedef serialized_integer_path_adaptor<int32, 6> path_adaptor_type; + typedef font_engine_win32_tt_base::gray8_adaptor_type gray8_adaptor_type; + typedef font_engine_win32_tt_base::mono_adaptor_type mono_adaptor_type; + typedef font_engine_win32_tt_base::scanlines_aa_type scanlines_aa_type; + typedef font_engine_win32_tt_base::scanlines_bin_type scanlines_bin_type; + + font_engine_win32_tt_int32(HDC dc, unsigned max_fonts = 32) : + font_engine_win32_tt_base(true, dc, max_fonts) {} + }; + + +} + +#endif diff --git a/gpc/Makefile.am b/gpc/Makefile.am new file mode 100644 index 0000000..b40648d --- /dev/null +++ b/gpc/Makefile.am @@ -0,0 +1,11 @@ +if ENABLE_GPC +lib_LTLIBRARIES = libagggpc.la +include_HEADERS=gpc.h +libagggpc_la_LDFLAGS = -no-undefined -version-info @AGG_LIB_VERSION@ +libagggpc_la_SOURCES = gpc.c + +EXTRA_DIST=copying.txt\ + VERSIONS.TXT\ + gpc.h + +endif diff --git a/gpc/VERSIONS.TXT b/gpc/VERSIONS.TXT new file mode 100644 index 0000000..8eeee67 --- /dev/null +++ b/gpc/VERSIONS.TXT @@ -0,0 +1,123 @@ + +Generic Polygon Clipper (gpc) Revision History +============================================== + + +v2.32 17th Dec 2004 +--------------------- + Fixed occasional memory leak occurring when processing some + degenerate polygon arrangements. + Added explicit type casting to memory allocator in support of + increased code portability. + +v2.31 4th Jun 1999 +--------------------- + Separated edge merging measure based on a user-defined GPC_EPSILON + value from general numeric equality testing and ordering, which now + uses direct arithmetic comparison rather an EPSILON based proximity + test. + Fixed problem with numerical equality test during construction of + local minima and scanbeam tables, leading to occasional crash. + Fixed hole array memory leak in gpc_add_contour. + Fixed uninitialised hole field bug in gpc_polygon_clip result. + +v2.30 11th Apr 1999 +--------------------- + Major re-write. + Minor API change: additional 'hole' array field added to gpc_polygon + datatype to indicate which constituent contours are internal holes, + and which form external boundaries. + Minor API change: additional 'hole' argument to gpc_add_contour + to indicate whether the new contour is a hole or external contour. + Minor API change: additional parameter to gpc_read_polygon and + gpc_write_polygon to indicate whether or not to read or write + contour hole flags. + Fixed NULL pointer bug in add/merge left/right operations. + Fixed numerical problem in intersection table generation. + Fixed zero byte malloc problem. + Fixed problem producing occasional 2 vertex contours. + Added bounding box test optimisations. + Simplified edge bundle creation, detection of scanbeam internal + edge intersections and tristrip scanbeam boundary code. + Renamed 'class' variable to be C++ friendly. + +v2.22 17th Oct 1998 +--------------------- + Re-implemented edge interpolation and intersection calculations + to improve numerical robustness. + Simplified setting of GPC_EPSILON. + +v2.21 19th Aug 1998 +--------------------- + Fixed problem causing occasional incorrect output when processing + self-intersecting polygons (bow-ties etc). + Removed bug which may lead to non-generation of uppermost triangle + in tristrip output. + +v2.20 26th May 1998 +--------------------- + Major re-write. + Added exclusive-or polygon set operation. + Replaced table-based processing of edge intersections with + rule-based system. + Replaced two-pass approach to scanbeam interior processing with + single pass method. + +v2.10a 14th May 1998 +--------------------- + Minor bug-fixes to counter some v2.10 reliability problems. + +v2.10 11th May 1998 +--------------------- + Major re-write. + Incorporated edge bundle processing of AET to overcome coincident + edge problems present in previous releases. + Replaced Vatti's method for processing scanbeam interior regions + with an adapted version of the scanbeam boundary processing + algorithm. + +v2.02 16th Apr 1998 (unreleased) +---------------------------------- + Fixed internal minimum vertex duplication in gpc_polygon_clip + result. + Improved line intersection code discourage superfluous + intersections near line ends. + Removed limited precision number formatting in gpc_write_polygon. + Modification to allow subject or clip polygon to be reused as the + result in gpc_polygon_clip without memory leakage. + +v2.01 23rd Feb 1998 +--------------------- + Removed bug causing duplicated vertices in output polygon. + Fixed scanbeam table index overrun problem. + +v2.00 25th Nov 1997 +--------------------- + Major re-write. + Replaced temporary horizontal edge work-around (using tilting) + with true horizontal edge handling. + Trapezoidal output replaced by tristrips. + gpc_op constants now feature a `GPC_' prefix. + Data structures now passed by reference to gpc functions. + Replaced AET search by proxy addressing in polygon table. + Eliminated most (all?) coincident vertex / edge crashes. + +v1.02 18th Oct 1997 (unreleased) +---------------------------------- + Significantly reduced number of mallocs in build_lmt. + Scanbeam table now built using heapsort rather than insertion + sort. + +v1.01 12th Oct 1997 +--------------------- + Fixed memory leak during output polygon build in + gpc_clip_polygon. + Removed superfluous logfile debug code. + Commented out malloc counts. + Added missing horizontal edge tilt-correction code in + gpc_clip_polygon. + +v1.00 8th Oct 1997 +-------------------- + First release. + diff --git a/gpc/copying.txt b/gpc/copying.txt new file mode 100644 index 0000000..0160fb4 --- /dev/null +++ b/gpc/copying.txt @@ -0,0 +1,22 @@ + + http://www.cs.man.ac.uk/aig/staff/alan/software/ + +Author: Alan Murta (email: gpc@cs.man.ac.uk) +Version: 2.31 +Date: 4th June 1999 + +Copyright: (C) 1997-1999, Advanced Interfaces Group, + University of Manchester. + + This software is free for non-commercial use. It may be copied, + modified, and redistributed provided that this copyright notice + is preserved on all copies. The intellectual property rights of + the algorithms used reside with the University of Manchester + Advanced Interfaces Group. + + You may not use this software, in whole or in part, in support + of any commercial product without the express consent of the + author. + + There is no warranty or other guarantee of fitness of this + software for any purpose. It is provided solely "as is". diff --git a/gpc/gpc.c b/gpc/gpc.c new file mode 100644 index 0000000..b9cce1b --- /dev/null +++ b/gpc/gpc.c @@ -0,0 +1,2472 @@ +/* +=========================================================================== + +Project: Generic Polygon Clipper + + A new algorithm for calculating the difference, intersection, + exclusive-or or union of arbitrary polygon sets. + +File: gpc.c +Author: Alan Murta (email: gpc@cs.man.ac.uk) +Version: 2.32 +Date: 17th December 2004 + +Copyright: (C) 1997-2004, Advanced Interfaces Group, + University of Manchester. + + This software is free for non-commercial use. It may be copied, + modified, and redistributed provided that this copyright notice + is preserved on all copies. The intellectual property rights of + the algorithms used reside with the University of Manchester + Advanced Interfaces Group. + + You may not use this software, in whole or in part, in support + of any commercial product without the express consent of the + author. + + There is no warranty or other guarantee of fitness of this + software for any purpose. It is provided solely "as is". + +=========================================================================== +*/ + + +/* +=========================================================================== + Includes +=========================================================================== +*/ + +#include "gpc.h" +#include <stdlib.h> +#include <float.h> +#include <math.h> + + +/* +=========================================================================== + Constants +=========================================================================== +*/ + +#ifndef TRUE +#define FALSE 0 +#define TRUE 1 +#endif + +#define LEFT 0 +#define RIGHT 1 + +#define ABOVE 0 +#define BELOW 1 + +#define CLIP 0 +#define SUBJ 1 + +#define INVERT_TRISTRIPS FALSE + + +/* +=========================================================================== + Macros +=========================================================================== +*/ + +#define EQ(a, b) (fabs((a) - (b)) <= GPC_EPSILON) + +#define PREV_INDEX(i, n) ((i - 1 + n) % n) +#define NEXT_INDEX(i, n) ((i + 1 ) % n) + +#define OPTIMAL(v, i, n) ((v[PREV_INDEX(i, n)].y != v[i].y) || \ + (v[NEXT_INDEX(i, n)].y != v[i].y)) + +#define FWD_MIN(v, i, n) ((v[PREV_INDEX(i, n)].vertex.y >= v[i].vertex.y) \ + && (v[NEXT_INDEX(i, n)].vertex.y > v[i].vertex.y)) + +#define NOT_FMAX(v, i, n) (v[NEXT_INDEX(i, n)].vertex.y > v[i].vertex.y) + +#define REV_MIN(v, i, n) ((v[PREV_INDEX(i, n)].vertex.y > v[i].vertex.y) \ + && (v[NEXT_INDEX(i, n)].vertex.y >= v[i].vertex.y)) + +#define NOT_RMAX(v, i, n) (v[PREV_INDEX(i, n)].vertex.y > v[i].vertex.y) + +#define VERTEX(e,p,s,x,y) {add_vertex(&((e)->outp[(p)]->v[(s)]), x, y); \ + (e)->outp[(p)]->active++;} + +#define P_EDGE(d,e,p,i,j) {(d)= (e); \ + do {(d)= (d)->prev;} while (!(d)->outp[(p)]); \ + (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);} + +#define N_EDGE(d,e,p,i,j) {(d)= (e); \ + do {(d)= (d)->next;} while (!(d)->outp[(p)]); \ + (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);} + +#define MALLOC(p, b, s, t) {if ((b) > 0) { \ + p= (t*)malloc(b); if (!(p)) { \ + fprintf(stderr, "gpc malloc failure: %s\n", s); \ + exit(0);}} else p= NULL;} + +#define FREE(p) {if (p) {free(p); (p)= NULL;}} + + +/* +=========================================================================== + Private Data Types +=========================================================================== +*/ + +typedef enum /* Edge intersection classes */ +{ + NUL, /* Empty non-intersection */ + EMX, /* External maximum */ + ELI, /* External left intermediate */ + TED, /* Top edge */ + ERI, /* External right intermediate */ + RED, /* Right edge */ + IMM, /* Internal maximum and minimum */ + IMN, /* Internal minimum */ + EMN, /* External minimum */ + EMM, /* External maximum and minimum */ + LED, /* Left edge */ + ILI, /* Internal left intermediate */ + BED, /* Bottom edge */ + IRI, /* Internal right intermediate */ + IMX, /* Internal maximum */ + FUL /* Full non-intersection */ +} vertex_type; + +typedef enum /* Horizontal edge states */ +{ + NH, /* No horizontal edge */ + BH, /* Bottom horizontal edge */ + TH /* Top horizontal edge */ +} h_state; + +typedef enum /* Edge bundle state */ +{ + UNBUNDLED, /* Isolated edge not within a bundle */ + BUNDLE_HEAD, /* Bundle head node */ + BUNDLE_TAIL /* Passive bundle tail node */ +} bundle_state; + +typedef struct v_shape /* Internal vertex list datatype */ +{ + double x; /* X coordinate component */ + double y; /* Y coordinate component */ + struct v_shape *next; /* Pointer to next vertex in list */ +} vertex_node; + +typedef struct p_shape /* Internal contour / tristrip type */ +{ + int active; /* Active flag / vertex count */ + int hole; /* Hole / external contour flag */ + vertex_node *v[2]; /* Left and right vertex list ptrs */ + struct p_shape *next; /* Pointer to next polygon contour */ + struct p_shape *proxy; /* Pointer to actual structure used */ +} polygon_node; + +typedef struct edge_shape +{ + gpc_vertex vertex; /* Piggy-backed contour vertex data */ + gpc_vertex bot; /* Edge lower (x, y) coordinate */ + gpc_vertex top; /* Edge upper (x, y) coordinate */ + double xb; /* Scanbeam bottom x coordinate */ + double xt; /* Scanbeam top x coordinate */ + double dx; /* Change in x for a unit y increase */ + int type; /* Clip / subject edge flag */ + int bundle[2][2]; /* Bundle edge flags */ + int bside[2]; /* Bundle left / right indicators */ + bundle_state bstate[2]; /* Edge bundle state */ + polygon_node *outp[2]; /* Output polygon / tristrip pointer */ + struct edge_shape *prev; /* Previous edge in the AET */ + struct edge_shape *next; /* Next edge in the AET */ + struct edge_shape *pred; /* Edge connected at the lower end */ + struct edge_shape *succ; /* Edge connected at the upper end */ + struct edge_shape *next_bound; /* Pointer to next bound in LMT */ +} edge_node; + +typedef struct lmt_shape /* Local minima table */ +{ + double y; /* Y coordinate at local minimum */ + edge_node *first_bound; /* Pointer to bound list */ + struct lmt_shape *next; /* Pointer to next local minimum */ +} lmt_node; + +typedef struct sbt_t_shape /* Scanbeam tree */ +{ + double y; /* Scanbeam node y value */ + struct sbt_t_shape *less; /* Pointer to nodes with lower y */ + struct sbt_t_shape *more; /* Pointer to nodes with higher y */ +} sb_tree; + +typedef struct it_shape /* Intersection table */ +{ + edge_node *ie[2]; /* Intersecting edge (bundle) pair */ + gpc_vertex point; /* Point of intersection */ + struct it_shape *next; /* The next intersection table node */ +} it_node; + +typedef struct st_shape /* Sorted edge table */ +{ + edge_node *edge; /* Pointer to AET edge */ + double xb; /* Scanbeam bottom x coordinate */ + double xt; /* Scanbeam top x coordinate */ + double dx; /* Change in x for a unit y increase */ + struct st_shape *prev; /* Previous edge in sorted list */ +} st_node; + +typedef struct bbox_shape /* Contour axis-aligned bounding box */ +{ + double xmin; /* Minimum x coordinate */ + double ymin; /* Minimum y coordinate */ + double xmax; /* Maximum x coordinate */ + double ymax; /* Maximum y coordinate */ +} bbox; + + +/* +=========================================================================== + Global Data +=========================================================================== +*/ + +/* Horizontal edge state transitions within scanbeam boundary */ +const h_state next_h_state[3][6]= +{ + /* ABOVE BELOW CROSS */ + /* L R L R L R */ + /* NH */ {BH, TH, TH, BH, NH, NH}, + /* BH */ {NH, NH, NH, NH, TH, TH}, + /* TH */ {NH, NH, NH, NH, BH, BH} +}; + + +/* +=========================================================================== + Private Functions +=========================================================================== +*/ + +static void reset_it(it_node **it) +{ + it_node *itn; + + while (*it) + { + itn= (*it)->next; + FREE(*it); + *it= itn; + } +} + + +static void reset_lmt(lmt_node **lmt) +{ + lmt_node *lmtn; + + while (*lmt) + { + lmtn= (*lmt)->next; + FREE(*lmt); + *lmt= lmtn; + } +} + + +static void insert_bound(edge_node **b, edge_node *e) +{ + edge_node *existing_bound; + + if (!*b) + { + /* Link node e to the tail of the list */ + *b= e; + } + else + { + /* Do primary sort on the x field */ + if (e[0].bot.x < (*b)[0].bot.x) + { + /* Insert a new node mid-list */ + existing_bound= *b; + *b= e; + (*b)->next_bound= existing_bound; + } + else + { + if (e[0].bot.x == (*b)[0].bot.x) + { + /* Do secondary sort on the dx field */ + if (e[0].dx < (*b)[0].dx) + { + /* Insert a new node mid-list */ + existing_bound= *b; + *b= e; + (*b)->next_bound= existing_bound; + } + else + { + /* Head further down the list */ + insert_bound(&((*b)->next_bound), e); + } + } + else + { + /* Head further down the list */ + insert_bound(&((*b)->next_bound), e); + } + } + } +} + + +static edge_node **bound_list(lmt_node **lmt, double y) +{ + lmt_node *existing_node; + + if (!*lmt) + { + /* Add node onto the tail end of the LMT */ + MALLOC(*lmt, sizeof(lmt_node), "LMT insertion", lmt_node); + (*lmt)->y= y; + (*lmt)->first_bound= NULL; + (*lmt)->next= NULL; + return &((*lmt)->first_bound); + } + else + if (y < (*lmt)->y) + { + /* Insert a new LMT node before the current node */ + existing_node= *lmt; + MALLOC(*lmt, sizeof(lmt_node), "LMT insertion", lmt_node); + (*lmt)->y= y; + (*lmt)->first_bound= NULL; + (*lmt)->next= existing_node; + return &((*lmt)->first_bound); + } + else + if (y > (*lmt)->y) + /* Head further up the LMT */ + return bound_list(&((*lmt)->next), y); + else + /* Use this existing LMT node */ + return &((*lmt)->first_bound); +} + + +static void add_to_sbtree(int *entries, sb_tree **sbtree, double y) +{ + if (!*sbtree) + { + /* Add a new tree node here */ + MALLOC(*sbtree, sizeof(sb_tree), "scanbeam tree insertion", sb_tree); + (*sbtree)->y= y; + (*sbtree)->less= NULL; + (*sbtree)->more= NULL; + (*entries)++; + } + else + { + if ((*sbtree)->y > y) + { + /* Head into the 'less' sub-tree */ + add_to_sbtree(entries, &((*sbtree)->less), y); + } + else + { + if ((*sbtree)->y < y) + { + /* Head into the 'more' sub-tree */ + add_to_sbtree(entries, &((*sbtree)->more), y); + } + } + } +} + + +static void build_sbt(int *entries, double *sbt, sb_tree *sbtree) +{ + if (sbtree->less) + build_sbt(entries, sbt, sbtree->less); + sbt[*entries]= sbtree->y; + (*entries)++; + if (sbtree->more) + build_sbt(entries, sbt, sbtree->more); +} + + +static void free_sbtree(sb_tree **sbtree) +{ + if (*sbtree) + { + free_sbtree(&((*sbtree)->less)); + free_sbtree(&((*sbtree)->more)); + FREE(*sbtree); + } +} + + +static int count_optimal_vertices(gpc_vertex_list c) +{ + int result= 0, i; + + /* Ignore non-contributing contours */ + if (c.num_vertices > 0) + { + for (i= 0; i < c.num_vertices; i++) + /* Ignore superfluous vertices embedded in horizontal edges */ + if (OPTIMAL(c.vertex, i, c.num_vertices)) + result++; + } + return result; +} + + +static edge_node *build_lmt(lmt_node **lmt, sb_tree **sbtree, + int *sbt_entries, gpc_polygon *p, int type, + gpc_op op) +{ + int c, i, min, max, num_edges, v, num_vertices; + int total_vertices= 0, e_index=0; + edge_node *e, *edge_table; + + for (c= 0; c < p->num_contours; c++) + total_vertices+= count_optimal_vertices(p->contour[c]); + + /* Create the entire input polygon edge table in one go */ + MALLOC(edge_table, total_vertices * sizeof(edge_node), + "edge table creation", edge_node); + + for (c= 0; c < p->num_contours; c++) + { + if (p->contour[c].num_vertices < 0) + { + /* Ignore the non-contributing contour and repair the vertex count */ + p->contour[c].num_vertices= -p->contour[c].num_vertices; + } + else + { + /* Perform contour optimisation */ + num_vertices= 0; + for (i= 0; i < p->contour[c].num_vertices; i++) + if (OPTIMAL(p->contour[c].vertex, i, p->contour[c].num_vertices)) + { + edge_table[num_vertices].vertex.x= p->contour[c].vertex[i].x; + edge_table[num_vertices].vertex.y= p->contour[c].vertex[i].y; + + /* Record vertex in the scanbeam table */ + add_to_sbtree(sbt_entries, sbtree, + edge_table[num_vertices].vertex.y); + + num_vertices++; + } + + /* Do the contour forward pass */ + for (min= 0; min < num_vertices; min++) + { + /* If a forward local minimum... */ + if (FWD_MIN(edge_table, min, num_vertices)) + { + /* Search for the next local maximum... */ + num_edges= 1; + max= NEXT_INDEX(min, num_vertices); + while (NOT_FMAX(edge_table, max, num_vertices)) + { + num_edges++; + max= NEXT_INDEX(max, num_vertices); + } + + /* Build the next edge list */ + e= &edge_table[e_index]; + e_index+= num_edges; + v= min; + e[0].bstate[BELOW]= UNBUNDLED; + e[0].bundle[BELOW][CLIP]= FALSE; + e[0].bundle[BELOW][SUBJ]= FALSE; + for (i= 0; i < num_edges; i++) + { + e[i].xb= edge_table[v].vertex.x; + e[i].bot.x= edge_table[v].vertex.x; + e[i].bot.y= edge_table[v].vertex.y; + + v= NEXT_INDEX(v, num_vertices); + + e[i].top.x= edge_table[v].vertex.x; + e[i].top.y= edge_table[v].vertex.y; + e[i].dx= (edge_table[v].vertex.x - e[i].bot.x) / + (e[i].top.y - e[i].bot.y); + e[i].type= type; + e[i].outp[ABOVE]= NULL; + e[i].outp[BELOW]= NULL; + e[i].next= NULL; + e[i].prev= NULL; + e[i].succ= ((num_edges > 1) && (i < (num_edges - 1))) ? + &(e[i + 1]) : NULL; + e[i].pred= ((num_edges > 1) && (i > 0)) ? &(e[i - 1]) : NULL; + e[i].next_bound= NULL; + e[i].bside[CLIP]= (op == GPC_DIFF) ? RIGHT : LEFT; + e[i].bside[SUBJ]= LEFT; + } + insert_bound(bound_list(lmt, edge_table[min].vertex.y), e); + } + } + + /* Do the contour reverse pass */ + for (min= 0; min < num_vertices; min++) + { + /* If a reverse local minimum... */ + if (REV_MIN(edge_table, min, num_vertices)) + { + /* Search for the previous local maximum... */ + num_edges= 1; + max= PREV_INDEX(min, num_vertices); + while (NOT_RMAX(edge_table, max, num_vertices)) + { + num_edges++; + max= PREV_INDEX(max, num_vertices); + } + + /* Build the previous edge list */ + e= &edge_table[e_index]; + e_index+= num_edges; + v= min; + e[0].bstate[BELOW]= UNBUNDLED; + e[0].bundle[BELOW][CLIP]= FALSE; + e[0].bundle[BELOW][SUBJ]= FALSE; + for (i= 0; i < num_edges; i++) + { + e[i].xb= edge_table[v].vertex.x; + e[i].bot.x= edge_table[v].vertex.x; + e[i].bot.y= edge_table[v].vertex.y; + + v= PREV_INDEX(v, num_vertices); + + e[i].top.x= edge_table[v].vertex.x; + e[i].top.y= edge_table[v].vertex.y; + e[i].dx= (edge_table[v].vertex.x - e[i].bot.x) / + (e[i].top.y - e[i].bot.y); + e[i].type= type; + e[i].outp[ABOVE]= NULL; + e[i].outp[BELOW]= NULL; + e[i].next= NULL; + e[i].prev= NULL; + e[i].succ= ((num_edges > 1) && (i < (num_edges - 1))) ? + &(e[i + 1]) : NULL; + e[i].pred= ((num_edges > 1) && (i > 0)) ? &(e[i - 1]) : NULL; + e[i].next_bound= NULL; + e[i].bside[CLIP]= (op == GPC_DIFF) ? RIGHT : LEFT; + e[i].bside[SUBJ]= LEFT; + } + insert_bound(bound_list(lmt, edge_table[min].vertex.y), e); + } + } + } + } + return edge_table; +} + + +static void add_edge_to_aet(edge_node **aet, edge_node *edge, edge_node *prev) +{ + if (!*aet) + { + /* Append edge onto the tail end of the AET */ + *aet= edge; + edge->prev= prev; + edge->next= NULL; + } + else + { + /* Do primary sort on the xb field */ + if (edge->xb < (*aet)->xb) + { + /* Insert edge here (before the AET edge) */ + edge->prev= prev; + edge->next= *aet; + (*aet)->prev= edge; + *aet= edge; + } + else + { + if (edge->xb == (*aet)->xb) + { + /* Do secondary sort on the dx field */ + if (edge->dx < (*aet)->dx) + { + /* Insert edge here (before the AET edge) */ + edge->prev= prev; + edge->next= *aet; + (*aet)->prev= edge; + *aet= edge; + } + else + { + /* Head further into the AET */ + add_edge_to_aet(&((*aet)->next), edge, *aet); + } + } + else + { + /* Head further into the AET */ + add_edge_to_aet(&((*aet)->next), edge, *aet); + } + } + } +} + + +static void add_intersection(it_node **it, edge_node *edge0, edge_node *edge1, + double x, double y) +{ + it_node *existing_node; + + if (!*it) + { + /* Append a new node to the tail of the list */ + MALLOC(*it, sizeof(it_node), "IT insertion", it_node); + (*it)->ie[0]= edge0; + (*it)->ie[1]= edge1; + (*it)->point.x= x; + (*it)->point.y= y; + (*it)->next= NULL; + } + else + { + if ((*it)->point.y > y) + { + /* Insert a new node mid-list */ + existing_node= *it; + MALLOC(*it, sizeof(it_node), "IT insertion", it_node); + (*it)->ie[0]= edge0; + (*it)->ie[1]= edge1; + (*it)->point.x= x; + (*it)->point.y= y; + (*it)->next= existing_node; + } + else + /* Head further down the list */ + add_intersection(&((*it)->next), edge0, edge1, x, y); + } +} + + +static void add_st_edge(st_node **st, it_node **it, edge_node *edge, + double dy) +{ + st_node *existing_node; + double den, r, x, y; + + if (!*st) + { + /* Append edge onto the tail end of the ST */ + MALLOC(*st, sizeof(st_node), "ST insertion", st_node); + (*st)->edge= edge; + (*st)->xb= edge->xb; + (*st)->xt= edge->xt; + (*st)->dx= edge->dx; + (*st)->prev= NULL; + } + else + { + den= ((*st)->xt - (*st)->xb) - (edge->xt - edge->xb); + + /* If new edge and ST edge don't cross */ + if ((edge->xt >= (*st)->xt) || (edge->dx == (*st)->dx) || + (fabs(den) <= DBL_EPSILON)) + { + /* No intersection - insert edge here (before the ST edge) */ + existing_node= *st; + MALLOC(*st, sizeof(st_node), "ST insertion", st_node); + (*st)->edge= edge; + (*st)->xb= edge->xb; + (*st)->xt= edge->xt; + (*st)->dx= edge->dx; + (*st)->prev= existing_node; + } + else + { + /* Compute intersection between new edge and ST edge */ + r= (edge->xb - (*st)->xb) / den; + x= (*st)->xb + r * ((*st)->xt - (*st)->xb); + y= r * dy; + + /* Insert the edge pointers and the intersection point in the IT */ + add_intersection(it, (*st)->edge, edge, x, y); + + /* Head further into the ST */ + add_st_edge(&((*st)->prev), it, edge, dy); + } + } +} + + +static void build_intersection_table(it_node **it, edge_node *aet, double dy) +{ + st_node *st, *stp; + edge_node *edge; + + /* Build intersection table for the current scanbeam */ + reset_it(it); + st= NULL; + + /* Process each AET edge */ + for (edge= aet; edge; edge= edge->next) + { + if ((edge->bstate[ABOVE] == BUNDLE_HEAD) || + edge->bundle[ABOVE][CLIP] || edge->bundle[ABOVE][SUBJ]) + add_st_edge(&st, it, edge, dy); + } + + /* Free the sorted edge table */ + while (st) + { + stp= st->prev; + FREE(st); + st= stp; + } +} + +static int count_contours(polygon_node *polygon) +{ + int nc, nv; + vertex_node *v, *nextv; + + for (nc= 0; polygon; polygon= polygon->next) + if (polygon->active) + { + /* Count the vertices in the current contour */ + nv= 0; + for (v= polygon->proxy->v[LEFT]; v; v= v->next) + nv++; + + /* Record valid vertex counts in the active field */ + if (nv > 2) + { + polygon->active= nv; + nc++; + } + else + { + /* Invalid contour: just free the heap */ + for (v= polygon->proxy->v[LEFT]; v; v= nextv) + { + nextv= v->next; + FREE(v); + } + polygon->active= 0; + } + } + return nc; +} + + +static void add_left(polygon_node *p, double x, double y) +{ + vertex_node *nv; + + /* Create a new vertex node and set its fields */ + MALLOC(nv, sizeof(vertex_node), "vertex node creation", vertex_node); + nv->x= x; + nv->y= y; + + /* Add vertex nv to the left end of the polygon's vertex list */ + nv->next= p->proxy->v[LEFT]; + + /* Update proxy->[LEFT] to point to nv */ + p->proxy->v[LEFT]= nv; +} + + +static void merge_left(polygon_node *p, polygon_node *q, polygon_node *list) +{ + polygon_node *target; + + /* Label contour as a hole */ + q->proxy->hole= TRUE; + + if (p->proxy != q->proxy) + { + /* Assign p's vertex list to the left end of q's list */ + p->proxy->v[RIGHT]->next= q->proxy->v[LEFT]; + q->proxy->v[LEFT]= p->proxy->v[LEFT]; + + /* Redirect any p->proxy references to q->proxy */ + + for (target= p->proxy; list; list= list->next) + { + if (list->proxy == target) + { + list->active= FALSE; + list->proxy= q->proxy; + } + } + } +} + + +static void add_right(polygon_node *p, double x, double y) +{ + vertex_node *nv; + + /* Create a new vertex node and set its fields */ + MALLOC(nv, sizeof(vertex_node), "vertex node creation", vertex_node); + nv->x= x; + nv->y= y; + nv->next= NULL; + + /* Add vertex nv to the right end of the polygon's vertex list */ + p->proxy->v[RIGHT]->next= nv; + + /* Update proxy->v[RIGHT] to point to nv */ + p->proxy->v[RIGHT]= nv; +} + + +static void merge_right(polygon_node *p, polygon_node *q, polygon_node *list) +{ + polygon_node *target; + + /* Label contour as external */ + q->proxy->hole= FALSE; + + if (p->proxy != q->proxy) + { + /* Assign p's vertex list to the right end of q's list */ + q->proxy->v[RIGHT]->next= p->proxy->v[LEFT]; + q->proxy->v[RIGHT]= p->proxy->v[RIGHT]; + + /* Redirect any p->proxy references to q->proxy */ + for (target= p->proxy; list; list= list->next) + { + if (list->proxy == target) + { + list->active= FALSE; + list->proxy= q->proxy; + } + } + } +} + + +static void add_local_min(polygon_node **p, edge_node *edge, + double x, double y) +{ + polygon_node *existing_min; + vertex_node *nv; + + existing_min= *p; + + MALLOC(*p, sizeof(polygon_node), "polygon node creation", polygon_node); + + /* Create a new vertex node and set its fields */ + MALLOC(nv, sizeof(vertex_node), "vertex node creation", vertex_node); + nv->x= x; + nv->y= y; + nv->next= NULL; + + /* Initialise proxy to point to p itself */ + (*p)->proxy= (*p); + (*p)->active= TRUE; + (*p)->next= existing_min; + + /* Make v[LEFT] and v[RIGHT] point to new vertex nv */ + (*p)->v[LEFT]= nv; + (*p)->v[RIGHT]= nv; + + /* Assign polygon p to the edge */ + edge->outp[ABOVE]= *p; +} + + +static int count_tristrips(polygon_node *tn) +{ + int total; + + for (total= 0; tn; tn= tn->next) + if (tn->active > 2) + total++; + return total; +} + + +static void add_vertex(vertex_node **t, double x, double y) +{ + if (!(*t)) + { + MALLOC(*t, sizeof(vertex_node), "tristrip vertex creation", vertex_node); + (*t)->x= x; + (*t)->y= y; + (*t)->next= NULL; + } + else + /* Head further down the list */ + add_vertex(&((*t)->next), x, y); +} + + +static void new_tristrip(polygon_node **tn, edge_node *edge, + double x, double y) +{ + if (!(*tn)) + { + MALLOC(*tn, sizeof(polygon_node), "tristrip node creation", polygon_node); + (*tn)->next= NULL; + (*tn)->v[LEFT]= NULL; + (*tn)->v[RIGHT]= NULL; + (*tn)->active= 1; + add_vertex(&((*tn)->v[LEFT]), x, y); + edge->outp[ABOVE]= *tn; + } + else + /* Head further down the list */ + new_tristrip(&((*tn)->next), edge, x, y); +} + + +static bbox *create_contour_bboxes(gpc_polygon *p) +{ + bbox *box; + int c, v; + + MALLOC(box, p->num_contours * sizeof(bbox), "Bounding box creation", bbox); + + /* Construct contour bounding boxes */ + for (c= 0; c < p->num_contours; c++) + { + /* Initialise bounding box extent */ + box[c].xmin= DBL_MAX; + box[c].ymin= DBL_MAX; + box[c].xmax= -DBL_MAX; + box[c].ymax= -DBL_MAX; + + for (v= 0; v < p->contour[c].num_vertices; v++) + { + /* Adjust bounding box */ + if (p->contour[c].vertex[v].x < box[c].xmin) + box[c].xmin= p->contour[c].vertex[v].x; + if (p->contour[c].vertex[v].y < box[c].ymin) + box[c].ymin= p->contour[c].vertex[v].y; + if (p->contour[c].vertex[v].x > box[c].xmax) + box[c].xmax= p->contour[c].vertex[v].x; + if (p->contour[c].vertex[v].y > box[c].ymax) + box[c].ymax= p->contour[c].vertex[v].y; + } + } + return box; +} + + +static void minimax_test(gpc_polygon *subj, gpc_polygon *clip, gpc_op op) +{ + bbox *s_bbox, *c_bbox; + int s, c, *o_table, overlap; + + s_bbox= create_contour_bboxes(subj); + c_bbox= create_contour_bboxes(clip); + + MALLOC(o_table, subj->num_contours * clip->num_contours * sizeof(int), + "overlap table creation", int); + + /* Check all subject contour bounding boxes against clip boxes */ + for (s= 0; s < subj->num_contours; s++) + for (c= 0; c < clip->num_contours; c++) + o_table[c * subj->num_contours + s]= + (!((s_bbox[s].xmax < c_bbox[c].xmin) || + (s_bbox[s].xmin > c_bbox[c].xmax))) && + (!((s_bbox[s].ymax < c_bbox[c].ymin) || + (s_bbox[s].ymin > c_bbox[c].ymax))); + + /* For each clip contour, search for any subject contour overlaps */ + for (c= 0; c < clip->num_contours; c++) + { + overlap= 0; + for (s= 0; (!overlap) && (s < subj->num_contours); s++) + overlap= o_table[c * subj->num_contours + s]; + + if (!overlap) + /* Flag non contributing status by negating vertex count */ + clip->contour[c].num_vertices = -clip->contour[c].num_vertices; + } + + if (op == GPC_INT) + { + /* For each subject contour, search for any clip contour overlaps */ + for (s= 0; s < subj->num_contours; s++) + { + overlap= 0; + for (c= 0; (!overlap) && (c < clip->num_contours); c++) + overlap= o_table[c * subj->num_contours + s]; + + if (!overlap) + /* Flag non contributing status by negating vertex count */ + subj->contour[s].num_vertices = -subj->contour[s].num_vertices; + } + } + + FREE(s_bbox); + FREE(c_bbox); + FREE(o_table); +} + + +/* +=========================================================================== + Public Functions +=========================================================================== +*/ + +void gpc_free_polygon(gpc_polygon *p) +{ + int c; + + for (c= 0; c < p->num_contours; c++) + FREE(p->contour[c].vertex); + FREE(p->hole); + FREE(p->contour); + p->num_contours= 0; +} + + +void gpc_read_polygon(FILE *fp, int read_hole_flags, gpc_polygon *p) +{ + int c, v; + + fscanf(fp, "%d", &(p->num_contours)); + MALLOC(p->hole, p->num_contours * sizeof(int), + "hole flag array creation", int); + MALLOC(p->contour, p->num_contours + * sizeof(gpc_vertex_list), "contour creation", gpc_vertex_list); + for (c= 0; c < p->num_contours; c++) + { + fscanf(fp, "%d", &(p->contour[c].num_vertices)); + + if (read_hole_flags) + fscanf(fp, "%d", &(p->hole[c])); + else + p->hole[c]= FALSE; /* Assume all contours to be external */ + + MALLOC(p->contour[c].vertex, p->contour[c].num_vertices + * sizeof(gpc_vertex), "vertex creation", gpc_vertex); + for (v= 0; v < p->contour[c].num_vertices; v++) + fscanf(fp, "%lf %lf", &(p->contour[c].vertex[v].x), + &(p->contour[c].vertex[v].y)); + } +} + + +void gpc_write_polygon(FILE *fp, int write_hole_flags, gpc_polygon *p) +{ + int c, v; + + fprintf(fp, "%d\n", p->num_contours); + for (c= 0; c < p->num_contours; c++) + { + fprintf(fp, "%d\n", p->contour[c].num_vertices); + + if (write_hole_flags) + fprintf(fp, "%d\n", p->hole[c]); + + for (v= 0; v < p->contour[c].num_vertices; v++) + fprintf(fp, "% .*lf % .*lf\n", + DBL_DIG, p->contour[c].vertex[v].x, + DBL_DIG, p->contour[c].vertex[v].y); + } +} + + +void gpc_add_contour(gpc_polygon *p, gpc_vertex_list *new_contour, int hole) +{ + int *extended_hole, c, v; + gpc_vertex_list *extended_contour; + + /* Create an extended hole array */ + MALLOC(extended_hole, (p->num_contours + 1) + * sizeof(int), "contour hole addition", int); + + /* Create an extended contour array */ + MALLOC(extended_contour, (p->num_contours + 1) + * sizeof(gpc_vertex_list), "contour addition", gpc_vertex_list); + + /* Copy the old contour and hole data into the extended arrays */ + for (c= 0; c < p->num_contours; c++) + { + extended_hole[c]= p->hole[c]; + extended_contour[c]= p->contour[c]; + } + + /* Copy the new contour and hole onto the end of the extended arrays */ + c= p->num_contours; + extended_hole[c]= hole; + extended_contour[c].num_vertices= new_contour->num_vertices; + MALLOC(extended_contour[c].vertex, new_contour->num_vertices + * sizeof(gpc_vertex), "contour addition", gpc_vertex); + for (v= 0; v < new_contour->num_vertices; v++) + extended_contour[c].vertex[v]= new_contour->vertex[v]; + + /* Dispose of the old contour */ + FREE(p->contour); + FREE(p->hole); + + /* Update the polygon information */ + p->num_contours++; + p->hole= extended_hole; + p->contour= extended_contour; +} + + +void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, + gpc_polygon *result) +{ + sb_tree *sbtree= NULL; + it_node *it= NULL, *intersect; + edge_node *edge, *prev_edge, *next_edge, *succ_edge, *e0, *e1; + edge_node *aet= NULL, *c_heap= NULL, *s_heap= NULL; + lmt_node *lmt= NULL, *local_min; + polygon_node *out_poly= NULL, *p, *q, *poly, *npoly, *cf= NULL; + vertex_node *vtx, *nv; + h_state horiz[2]; + int in[2], exists[2], parity[2]= {LEFT, LEFT}; + int c, v, contributing, search, scanbeam= 0, sbt_entries= 0; + int vclass, bl, br, tl, tr; + double *sbt= NULL, xb, px, yb, yt, dy, ix, iy; + + /* Test for trivial NULL result cases */ + if (((subj->num_contours == 0) && (clip->num_contours == 0)) + || ((subj->num_contours == 0) && ((op == GPC_INT) || (op == GPC_DIFF))) + || ((clip->num_contours == 0) && (op == GPC_INT))) + { + result->num_contours= 0; + result->hole= NULL; + result->contour= NULL; + return; + } + + /* Identify potentialy contributing contours */ + if (((op == GPC_INT) || (op == GPC_DIFF)) + && (subj->num_contours > 0) && (clip->num_contours > 0)) + minimax_test(subj, clip, op); + + /* Build LMT */ + if (subj->num_contours > 0) + s_heap= build_lmt(&lmt, &sbtree, &sbt_entries, subj, SUBJ, op); + if (clip->num_contours > 0) + c_heap= build_lmt(&lmt, &sbtree, &sbt_entries, clip, CLIP, op); + + /* Return a NULL result if no contours contribute */ + if (lmt == NULL) + { + result->num_contours= 0; + result->hole= NULL; + result->contour= NULL; + reset_lmt(&lmt); + FREE(s_heap); + FREE(c_heap); + return; + } + + /* Build scanbeam table from scanbeam tree */ + MALLOC(sbt, sbt_entries * sizeof(double), "sbt creation", double); + build_sbt(&scanbeam, sbt, sbtree); + scanbeam= 0; + free_sbtree(&sbtree); + + /* Allow pointer re-use without causing memory leak */ + if (subj == result) + gpc_free_polygon(subj); + if (clip == result) + gpc_free_polygon(clip); + + /* Invert clip polygon for difference operation */ + if (op == GPC_DIFF) + parity[CLIP]= RIGHT; + + local_min= lmt; + + /* Process each scanbeam */ + while (scanbeam < sbt_entries) + { + /* Set yb and yt to the bottom and top of the scanbeam */ + yb= sbt[scanbeam++]; + if (scanbeam < sbt_entries) + { + yt= sbt[scanbeam]; + dy= yt - yb; + } + + /* === SCANBEAM BOUNDARY PROCESSING ================================ */ + + /* If LMT node corresponding to yb exists */ + if (local_min) + { + if (local_min->y == yb) + { + /* Add edges starting at this local minimum to the AET */ + for (edge= local_min->first_bound; edge; edge= edge->next_bound) + add_edge_to_aet(&aet, edge, NULL); + + local_min= local_min->next; + } + } + + /* Set dummy previous x value */ + px= -DBL_MAX; + + /* Create bundles within AET */ + e0= aet; + e1= aet; + + /* Set up bundle fields of first edge */ + aet->bundle[ABOVE][ aet->type]= (aet->top.y != yb); + aet->bundle[ABOVE][!aet->type]= FALSE; + aet->bstate[ABOVE]= UNBUNDLED; + + for (next_edge= aet->next; next_edge; next_edge= next_edge->next) + { + /* Set up bundle fields of next edge */ + next_edge->bundle[ABOVE][ next_edge->type]= (next_edge->top.y != yb); + next_edge->bundle[ABOVE][!next_edge->type]= FALSE; + next_edge->bstate[ABOVE]= UNBUNDLED; + + /* Bundle edges above the scanbeam boundary if they coincide */ + if (next_edge->bundle[ABOVE][next_edge->type]) + { + if (EQ(e0->xb, next_edge->xb) && EQ(e0->dx, next_edge->dx) + && (e0->top.y != yb)) + { + next_edge->bundle[ABOVE][ next_edge->type]^= + e0->bundle[ABOVE][ next_edge->type]; + next_edge->bundle[ABOVE][!next_edge->type]= + e0->bundle[ABOVE][!next_edge->type]; + next_edge->bstate[ABOVE]= BUNDLE_HEAD; + e0->bundle[ABOVE][CLIP]= FALSE; + e0->bundle[ABOVE][SUBJ]= FALSE; + e0->bstate[ABOVE]= BUNDLE_TAIL; + } + e0= next_edge; + } + } + + horiz[CLIP]= NH; + horiz[SUBJ]= NH; + + /* Process each edge at this scanbeam boundary */ + for (edge= aet; edge; edge= edge->next) + { + exists[CLIP]= edge->bundle[ABOVE][CLIP] + + (edge->bundle[BELOW][CLIP] << 1); + exists[SUBJ]= edge->bundle[ABOVE][SUBJ] + + (edge->bundle[BELOW][SUBJ] << 1); + + if (exists[CLIP] || exists[SUBJ]) + { + /* Set bundle side */ + edge->bside[CLIP]= parity[CLIP]; + edge->bside[SUBJ]= parity[SUBJ]; + + /* Determine contributing status and quadrant occupancies */ + switch (op) + { + case GPC_DIFF: + case GPC_INT: + contributing= (exists[CLIP] && (parity[SUBJ] || horiz[SUBJ])) + || (exists[SUBJ] && (parity[CLIP] || horiz[CLIP])) + || (exists[CLIP] && exists[SUBJ] + && (parity[CLIP] == parity[SUBJ])); + br= (parity[CLIP]) + && (parity[SUBJ]); + bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP]) + && (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]); + tr= (parity[CLIP] ^ (horiz[CLIP]!=NH)) + && (parity[SUBJ] ^ (horiz[SUBJ]!=NH)); + tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP]) + && (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]); + break; + case GPC_XOR: + contributing= exists[CLIP] || exists[SUBJ]; + br= (parity[CLIP]) + ^ (parity[SUBJ]); + bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP]) + ^ (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]); + tr= (parity[CLIP] ^ (horiz[CLIP]!=NH)) + ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH)); + tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP]) + ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]); + break; + case GPC_UNION: + contributing= (exists[CLIP] && (!parity[SUBJ] || horiz[SUBJ])) + || (exists[SUBJ] && (!parity[CLIP] || horiz[CLIP])) + || (exists[CLIP] && exists[SUBJ] + && (parity[CLIP] == parity[SUBJ])); + br= (parity[CLIP]) + || (parity[SUBJ]); + bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP]) + || (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]); + tr= (parity[CLIP] ^ (horiz[CLIP]!=NH)) + || (parity[SUBJ] ^ (horiz[SUBJ]!=NH)); + tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP]) + || (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]); + break; + } + + /* Update parity */ + parity[CLIP]^= edge->bundle[ABOVE][CLIP]; + parity[SUBJ]^= edge->bundle[ABOVE][SUBJ]; + + /* Update horizontal state */ + if (exists[CLIP]) + horiz[CLIP]= + next_h_state[horiz[CLIP]] + [((exists[CLIP] - 1) << 1) + parity[CLIP]]; + if (exists[SUBJ]) + horiz[SUBJ]= + next_h_state[horiz[SUBJ]] + [((exists[SUBJ] - 1) << 1) + parity[SUBJ]]; + + vclass= tr + (tl << 1) + (br << 2) + (bl << 3); + + if (contributing) + { + xb= edge->xb; + + switch (vclass) + { + case EMN: + case IMN: + add_local_min(&out_poly, edge, xb, yb); + px= xb; + cf= edge->outp[ABOVE]; + break; + case ERI: + if (xb != px) + { + add_right(cf, xb, yb); + px= xb; + } + edge->outp[ABOVE]= cf; + cf= NULL; + break; + case ELI: + add_left(edge->outp[BELOW], xb, yb); + px= xb; + cf= edge->outp[BELOW]; + break; + case EMX: + if (xb != px) + { + add_left(cf, xb, yb); + px= xb; + } + merge_right(cf, edge->outp[BELOW], out_poly); + cf= NULL; + break; + case ILI: + if (xb != px) + { + add_left(cf, xb, yb); + px= xb; + } + edge->outp[ABOVE]= cf; + cf= NULL; + break; + case IRI: + add_right(edge->outp[BELOW], xb, yb); + px= xb; + cf= edge->outp[BELOW]; + edge->outp[BELOW]= NULL; + break; + case IMX: + if (xb != px) + { + add_right(cf, xb, yb); + px= xb; + } + merge_left(cf, edge->outp[BELOW], out_poly); + cf= NULL; + edge->outp[BELOW]= NULL; + break; + case IMM: + if (xb != px) + { + add_right(cf, xb, yb); + px= xb; + } + merge_left(cf, edge->outp[BELOW], out_poly); + edge->outp[BELOW]= NULL; + add_local_min(&out_poly, edge, xb, yb); + cf= edge->outp[ABOVE]; + break; + case EMM: + if (xb != px) + { + add_left(cf, xb, yb); + px= xb; + } + merge_right(cf, edge->outp[BELOW], out_poly); + edge->outp[BELOW]= NULL; + add_local_min(&out_poly, edge, xb, yb); + cf= edge->outp[ABOVE]; + break; + case LED: + if (edge->bot.y == yb) + add_left(edge->outp[BELOW], xb, yb); + edge->outp[ABOVE]= edge->outp[BELOW]; + px= xb; + break; + case RED: + if (edge->bot.y == yb) + add_right(edge->outp[BELOW], xb, yb); + edge->outp[ABOVE]= edge->outp[BELOW]; + px= xb; + break; + default: + break; + } /* End of switch */ + } /* End of contributing conditional */ + } /* End of edge exists conditional */ + } /* End of AET loop */ + + /* Delete terminating edges from the AET, otherwise compute xt */ + for (edge= aet; edge; edge= edge->next) + { + if (edge->top.y == yb) + { + prev_edge= edge->prev; + next_edge= edge->next; + if (prev_edge) + prev_edge->next= next_edge; + else + aet= next_edge; + if (next_edge) + next_edge->prev= prev_edge; + + /* Copy bundle head state to the adjacent tail edge if required */ + if ((edge->bstate[BELOW] == BUNDLE_HEAD) && prev_edge) + { + if (prev_edge->bstate[BELOW] == BUNDLE_TAIL) + { + prev_edge->outp[BELOW]= edge->outp[BELOW]; + prev_edge->bstate[BELOW]= UNBUNDLED; + if (prev_edge->prev) + if (prev_edge->prev->bstate[BELOW] == BUNDLE_TAIL) + prev_edge->bstate[BELOW]= BUNDLE_HEAD; + } + } + } + else + { + if (edge->top.y == yt) + edge->xt= edge->top.x; + else + edge->xt= edge->bot.x + edge->dx * (yt - edge->bot.y); + } + } + + if (scanbeam < sbt_entries) + { + /* === SCANBEAM INTERIOR PROCESSING ============================== */ + + build_intersection_table(&it, aet, dy); + + /* Process each node in the intersection table */ + for (intersect= it; intersect; intersect= intersect->next) + { + e0= intersect->ie[0]; + e1= intersect->ie[1]; + + /* Only generate output for contributing intersections */ + if ((e0->bundle[ABOVE][CLIP] || e0->bundle[ABOVE][SUBJ]) + && (e1->bundle[ABOVE][CLIP] || e1->bundle[ABOVE][SUBJ])) + { + p= e0->outp[ABOVE]; + q= e1->outp[ABOVE]; + ix= intersect->point.x; + iy= intersect->point.y + yb; + + in[CLIP]= ( e0->bundle[ABOVE][CLIP] && !e0->bside[CLIP]) + || ( e1->bundle[ABOVE][CLIP] && e1->bside[CLIP]) + || (!e0->bundle[ABOVE][CLIP] && !e1->bundle[ABOVE][CLIP] + && e0->bside[CLIP] && e1->bside[CLIP]); + in[SUBJ]= ( e0->bundle[ABOVE][SUBJ] && !e0->bside[SUBJ]) + || ( e1->bundle[ABOVE][SUBJ] && e1->bside[SUBJ]) + || (!e0->bundle[ABOVE][SUBJ] && !e1->bundle[ABOVE][SUBJ] + && e0->bside[SUBJ] && e1->bside[SUBJ]); + + /* Determine quadrant occupancies */ + switch (op) + { + case GPC_DIFF: + case GPC_INT: + tr= (in[CLIP]) + && (in[SUBJ]); + tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP]) + && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]); + br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP]) + && (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP]) + && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + break; + case GPC_XOR: + tr= (in[CLIP]) + ^ (in[SUBJ]); + tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP]) + ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]); + br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP]) + ^ (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP]) + ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + break; + case GPC_UNION: + tr= (in[CLIP]) + || (in[SUBJ]); + tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP]) + || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]); + br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP]) + || (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP]) + || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + break; + } + + vclass= tr + (tl << 1) + (br << 2) + (bl << 3); + + switch (vclass) + { + case EMN: + add_local_min(&out_poly, e0, ix, iy); + e1->outp[ABOVE]= e0->outp[ABOVE]; + break; + case ERI: + if (p) + { + add_right(p, ix, iy); + e1->outp[ABOVE]= p; + e0->outp[ABOVE]= NULL; + } + break; + case ELI: + if (q) + { + add_left(q, ix, iy); + e0->outp[ABOVE]= q; + e1->outp[ABOVE]= NULL; + } + break; + case EMX: + if (p && q) + { + add_left(p, ix, iy); + merge_right(p, q, out_poly); + e0->outp[ABOVE]= NULL; + e1->outp[ABOVE]= NULL; + } + break; + case IMN: + add_local_min(&out_poly, e0, ix, iy); + e1->outp[ABOVE]= e0->outp[ABOVE]; + break; + case ILI: + if (p) + { + add_left(p, ix, iy); + e1->outp[ABOVE]= p; + e0->outp[ABOVE]= NULL; + } + break; + case IRI: + if (q) + { + add_right(q, ix, iy); + e0->outp[ABOVE]= q; + e1->outp[ABOVE]= NULL; + } + break; + case IMX: + if (p && q) + { + add_right(p, ix, iy); + merge_left(p, q, out_poly); + e0->outp[ABOVE]= NULL; + e1->outp[ABOVE]= NULL; + } + break; + case IMM: + if (p && q) + { + add_right(p, ix, iy); + merge_left(p, q, out_poly); + add_local_min(&out_poly, e0, ix, iy); + e1->outp[ABOVE]= e0->outp[ABOVE]; + } + break; + case EMM: + if (p && q) + { + add_left(p, ix, iy); + merge_right(p, q, out_poly); + add_local_min(&out_poly, e0, ix, iy); + e1->outp[ABOVE]= e0->outp[ABOVE]; + } + break; + default: + break; + } /* End of switch */ + } /* End of contributing intersection conditional */ + + /* Swap bundle sides in response to edge crossing */ + if (e0->bundle[ABOVE][CLIP]) + e1->bside[CLIP]= !e1->bside[CLIP]; + if (e1->bundle[ABOVE][CLIP]) + e0->bside[CLIP]= !e0->bside[CLIP]; + if (e0->bundle[ABOVE][SUBJ]) + e1->bside[SUBJ]= !e1->bside[SUBJ]; + if (e1->bundle[ABOVE][SUBJ]) + e0->bside[SUBJ]= !e0->bside[SUBJ]; + + /* Swap e0 and e1 bundles in the AET */ + prev_edge= e0->prev; + next_edge= e1->next; + if (next_edge) + next_edge->prev= e0; + + if (e0->bstate[ABOVE] == BUNDLE_HEAD) + { + search= TRUE; + while (search) + { + prev_edge= prev_edge->prev; + if (prev_edge) + { + if (prev_edge->bstate[ABOVE] != BUNDLE_TAIL) + search= FALSE; + } + else + search= FALSE; + } + } + if (!prev_edge) + { + aet->prev= e1; + e1->next= aet; + aet= e0->next; + } + else + { + prev_edge->next->prev= e1; + e1->next= prev_edge->next; + prev_edge->next= e0->next; + } + e0->next->prev= prev_edge; + e1->next->prev= e1; + e0->next= next_edge; + } /* End of IT loop*/ + + /* Prepare for next scanbeam */ + for (edge= aet; edge; edge= next_edge) + { + next_edge= edge->next; + succ_edge= edge->succ; + + if ((edge->top.y == yt) && succ_edge) + { + /* Replace AET edge by its successor */ + succ_edge->outp[BELOW]= edge->outp[ABOVE]; + succ_edge->bstate[BELOW]= edge->bstate[ABOVE]; + succ_edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP]; + succ_edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ]; + prev_edge= edge->prev; + if (prev_edge) + prev_edge->next= succ_edge; + else + aet= succ_edge; + if (next_edge) + next_edge->prev= succ_edge; + succ_edge->prev= prev_edge; + succ_edge->next= next_edge; + } + else + { + /* Update this edge */ + edge->outp[BELOW]= edge->outp[ABOVE]; + edge->bstate[BELOW]= edge->bstate[ABOVE]; + edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP]; + edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ]; + edge->xb= edge->xt; + } + edge->outp[ABOVE]= NULL; + } + } + } /* === END OF SCANBEAM PROCESSING ================================== */ + + /* Generate result polygon from out_poly */ + result->contour= NULL; + result->hole= NULL; + result->num_contours= count_contours(out_poly); + if (result->num_contours > 0) + { + MALLOC(result->hole, result->num_contours + * sizeof(int), "hole flag table creation", int); + MALLOC(result->contour, result->num_contours + * sizeof(gpc_vertex_list), "contour creation", gpc_vertex_list); + + c= 0; + for (poly= out_poly; poly; poly= npoly) + { + npoly= poly->next; + if (poly->active) + { + result->hole[c]= poly->proxy->hole; + result->contour[c].num_vertices= poly->active; + MALLOC(result->contour[c].vertex, + result->contour[c].num_vertices * sizeof(gpc_vertex), + "vertex creation", gpc_vertex); + + v= result->contour[c].num_vertices - 1; + for (vtx= poly->proxy->v[LEFT]; vtx; vtx= nv) + { + nv= vtx->next; + result->contour[c].vertex[v].x= vtx->x; + result->contour[c].vertex[v].y= vtx->y; + FREE(vtx); + v--; + } + c++; + } + FREE(poly); + } + } + else + { + for (poly= out_poly; poly; poly= npoly) + { + npoly= poly->next; + FREE(poly); + } + } + + /* Tidy up */ + reset_it(&it); + reset_lmt(&lmt); + FREE(c_heap); + FREE(s_heap); + FREE(sbt); +} + + +void gpc_free_tristrip(gpc_tristrip *t) +{ + int s; + + for (s= 0; s < t->num_strips; s++) + FREE(t->strip[s].vertex); + FREE(t->strip); + t->num_strips= 0; +} + + +void gpc_polygon_to_tristrip(gpc_polygon *s, gpc_tristrip *t) +{ + gpc_polygon c; + + c.num_contours= 0; + c.hole= NULL; + c.contour= NULL; + gpc_tristrip_clip(GPC_DIFF, s, &c, t); +} + + +void gpc_tristrip_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip, + gpc_tristrip *result) +{ + sb_tree *sbtree= NULL; + it_node *it= NULL, *intersect; + edge_node *edge, *prev_edge, *next_edge, *succ_edge, *e0, *e1; + edge_node *aet= NULL, *c_heap= NULL, *s_heap= NULL, *cf; + lmt_node *lmt= NULL, *local_min; + polygon_node *tlist= NULL, *tn, *tnn, *p, *q; + vertex_node *lt, *ltn, *rt, *rtn; + h_state horiz[2]; + vertex_type cft; + int in[2], exists[2], parity[2]= {LEFT, LEFT}; + int s, v, contributing, search, scanbeam= 0, sbt_entries= 0; + int vclass, bl, br, tl, tr; + double *sbt= NULL, xb, px, nx, yb, yt, dy, ix, iy; + + /* Test for trivial NULL result cases */ + if (((subj->num_contours == 0) && (clip->num_contours == 0)) + || ((subj->num_contours == 0) && ((op == GPC_INT) || (op == GPC_DIFF))) + || ((clip->num_contours == 0) && (op == GPC_INT))) + { + result->num_strips= 0; + result->strip= NULL; + return; + } + + /* Identify potentialy contributing contours */ + if (((op == GPC_INT) || (op == GPC_DIFF)) + && (subj->num_contours > 0) && (clip->num_contours > 0)) + minimax_test(subj, clip, op); + + /* Build LMT */ + if (subj->num_contours > 0) + s_heap= build_lmt(&lmt, &sbtree, &sbt_entries, subj, SUBJ, op); + if (clip->num_contours > 0) + c_heap= build_lmt(&lmt, &sbtree, &sbt_entries, clip, CLIP, op); + + /* Return a NULL result if no contours contribute */ + if (lmt == NULL) + { + result->num_strips= 0; + result->strip= NULL; + reset_lmt(&lmt); + FREE(s_heap); + FREE(c_heap); + return; + } + + /* Build scanbeam table from scanbeam tree */ + MALLOC(sbt, sbt_entries * sizeof(double), "sbt creation", double); + build_sbt(&scanbeam, sbt, sbtree); + scanbeam= 0; + free_sbtree(&sbtree); + + /* Invert clip polygon for difference operation */ + if (op == GPC_DIFF) + parity[CLIP]= RIGHT; + + local_min= lmt; + + /* Process each scanbeam */ + while (scanbeam < sbt_entries) + { + /* Set yb and yt to the bottom and top of the scanbeam */ + yb= sbt[scanbeam++]; + if (scanbeam < sbt_entries) + { + yt= sbt[scanbeam]; + dy= yt - yb; + } + + /* === SCANBEAM BOUNDARY PROCESSING ================================ */ + + /* If LMT node corresponding to yb exists */ + if (local_min) + { + if (local_min->y == yb) + { + /* Add edges starting at this local minimum to the AET */ + for (edge= local_min->first_bound; edge; edge= edge->next_bound) + add_edge_to_aet(&aet, edge, NULL); + + local_min= local_min->next; + } + } + + /* Set dummy previous x value */ + px= -DBL_MAX; + + /* Create bundles within AET */ + e0= aet; + e1= aet; + + /* Set up bundle fields of first edge */ + aet->bundle[ABOVE][ aet->type]= (aet->top.y != yb); + aet->bundle[ABOVE][!aet->type]= FALSE; + aet->bstate[ABOVE]= UNBUNDLED; + + for (next_edge= aet->next; next_edge; next_edge= next_edge->next) + { + /* Set up bundle fields of next edge */ + next_edge->bundle[ABOVE][ next_edge->type]= (next_edge->top.y != yb); + next_edge->bundle[ABOVE][!next_edge->type]= FALSE; + next_edge->bstate[ABOVE]= UNBUNDLED; + + /* Bundle edges above the scanbeam boundary if they coincide */ + if (next_edge->bundle[ABOVE][next_edge->type]) + { + if (EQ(e0->xb, next_edge->xb) && EQ(e0->dx, next_edge->dx) + && (e0->top.y != yb)) + { + next_edge->bundle[ABOVE][ next_edge->type]^= + e0->bundle[ABOVE][ next_edge->type]; + next_edge->bundle[ABOVE][!next_edge->type]= + e0->bundle[ABOVE][!next_edge->type]; + next_edge->bstate[ABOVE]= BUNDLE_HEAD; + e0->bundle[ABOVE][CLIP]= FALSE; + e0->bundle[ABOVE][SUBJ]= FALSE; + e0->bstate[ABOVE]= BUNDLE_TAIL; + } + e0= next_edge; + } + } + + horiz[CLIP]= NH; + horiz[SUBJ]= NH; + + /* Process each edge at this scanbeam boundary */ + for (edge= aet; edge; edge= edge->next) + { + exists[CLIP]= edge->bundle[ABOVE][CLIP] + + (edge->bundle[BELOW][CLIP] << 1); + exists[SUBJ]= edge->bundle[ABOVE][SUBJ] + + (edge->bundle[BELOW][SUBJ] << 1); + + if (exists[CLIP] || exists[SUBJ]) + { + /* Set bundle side */ + edge->bside[CLIP]= parity[CLIP]; + edge->bside[SUBJ]= parity[SUBJ]; + + /* Determine contributing status and quadrant occupancies */ + switch (op) + { + case GPC_DIFF: + case GPC_INT: + contributing= (exists[CLIP] && (parity[SUBJ] || horiz[SUBJ])) + || (exists[SUBJ] && (parity[CLIP] || horiz[CLIP])) + || (exists[CLIP] && exists[SUBJ] + && (parity[CLIP] == parity[SUBJ])); + br= (parity[CLIP]) + && (parity[SUBJ]); + bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP]) + && (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]); + tr= (parity[CLIP] ^ (horiz[CLIP]!=NH)) + && (parity[SUBJ] ^ (horiz[SUBJ]!=NH)); + tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP]) + && (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]); + break; + case GPC_XOR: + contributing= exists[CLIP] || exists[SUBJ]; + br= (parity[CLIP]) + ^ (parity[SUBJ]); + bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP]) + ^ (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]); + tr= (parity[CLIP] ^ (horiz[CLIP]!=NH)) + ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH)); + tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP]) + ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]); + break; + case GPC_UNION: + contributing= (exists[CLIP] && (!parity[SUBJ] || horiz[SUBJ])) + || (exists[SUBJ] && (!parity[CLIP] || horiz[CLIP])) + || (exists[CLIP] && exists[SUBJ] + && (parity[CLIP] == parity[SUBJ])); + br= (parity[CLIP]) + || (parity[SUBJ]); + bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP]) + || (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]); + tr= (parity[CLIP] ^ (horiz[CLIP]!=NH)) + || (parity[SUBJ] ^ (horiz[SUBJ]!=NH)); + tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP]) + || (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]); + break; + } + + /* Update parity */ + parity[CLIP]^= edge->bundle[ABOVE][CLIP]; + parity[SUBJ]^= edge->bundle[ABOVE][SUBJ]; + + /* Update horizontal state */ + if (exists[CLIP]) + horiz[CLIP]= + next_h_state[horiz[CLIP]] + [((exists[CLIP] - 1) << 1) + parity[CLIP]]; + if (exists[SUBJ]) + horiz[SUBJ]= + next_h_state[horiz[SUBJ]] + [((exists[SUBJ] - 1) << 1) + parity[SUBJ]]; + + vclass= tr + (tl << 1) + (br << 2) + (bl << 3); + + if (contributing) + { + xb= edge->xb; + + switch (vclass) + { + case EMN: + new_tristrip(&tlist, edge, xb, yb); + cf= edge; + break; + case ERI: + edge->outp[ABOVE]= cf->outp[ABOVE]; + if (xb != cf->xb) + VERTEX(edge, ABOVE, RIGHT, xb, yb); + cf= NULL; + break; + case ELI: + VERTEX(edge, BELOW, LEFT, xb, yb); + edge->outp[ABOVE]= NULL; + cf= edge; + break; + case EMX: + if (xb != cf->xb) + VERTEX(edge, BELOW, RIGHT, xb, yb); + edge->outp[ABOVE]= NULL; + cf= NULL; + break; + case IMN: + if (cft == LED) + { + if (cf->bot.y != yb) + VERTEX(cf, BELOW, LEFT, cf->xb, yb); + new_tristrip(&tlist, cf, cf->xb, yb); + } + edge->outp[ABOVE]= cf->outp[ABOVE]; + VERTEX(edge, ABOVE, RIGHT, xb, yb); + break; + case ILI: + new_tristrip(&tlist, edge, xb, yb); + cf= edge; + cft= ILI; + break; + case IRI: + if (cft == LED) + { + if (cf->bot.y != yb) + VERTEX(cf, BELOW, LEFT, cf->xb, yb); + new_tristrip(&tlist, cf, cf->xb, yb); + } + VERTEX(edge, BELOW, RIGHT, xb, yb); + edge->outp[ABOVE]= NULL; + break; + case IMX: + VERTEX(edge, BELOW, LEFT, xb, yb); + edge->outp[ABOVE]= NULL; + cft= IMX; + break; + case IMM: + VERTEX(edge, BELOW, LEFT, xb, yb); + edge->outp[ABOVE]= cf->outp[ABOVE]; + if (xb != cf->xb) + VERTEX(cf, ABOVE, RIGHT, xb, yb); + cf= edge; + break; + case EMM: + VERTEX(edge, BELOW, RIGHT, xb, yb); + edge->outp[ABOVE]= NULL; + new_tristrip(&tlist, edge, xb, yb); + cf= edge; + break; + case LED: + if (edge->bot.y == yb) + VERTEX(edge, BELOW, LEFT, xb, yb); + edge->outp[ABOVE]= edge->outp[BELOW]; + cf= edge; + cft= LED; + break; + case RED: + edge->outp[ABOVE]= cf->outp[ABOVE]; + if (cft == LED) + { + if (cf->bot.y == yb) + { + VERTEX(edge, BELOW, RIGHT, xb, yb); + } + else + { + if (edge->bot.y == yb) + { + VERTEX(cf, BELOW, LEFT, cf->xb, yb); + VERTEX(edge, BELOW, RIGHT, xb, yb); + } + } + } + else + { + VERTEX(edge, BELOW, RIGHT, xb, yb); + VERTEX(edge, ABOVE, RIGHT, xb, yb); + } + cf= NULL; + break; + default: + break; + } /* End of switch */ + } /* End of contributing conditional */ + } /* End of edge exists conditional */ + } /* End of AET loop */ + + /* Delete terminating edges from the AET, otherwise compute xt */ + for (edge= aet; edge; edge= edge->next) + { + if (edge->top.y == yb) + { + prev_edge= edge->prev; + next_edge= edge->next; + if (prev_edge) + prev_edge->next= next_edge; + else + aet= next_edge; + if (next_edge) + next_edge->prev= prev_edge; + + /* Copy bundle head state to the adjacent tail edge if required */ + if ((edge->bstate[BELOW] == BUNDLE_HEAD) && prev_edge) + { + if (prev_edge->bstate[BELOW] == BUNDLE_TAIL) + { + prev_edge->outp[BELOW]= edge->outp[BELOW]; + prev_edge->bstate[BELOW]= UNBUNDLED; + if (prev_edge->prev) + if (prev_edge->prev->bstate[BELOW] == BUNDLE_TAIL) + prev_edge->bstate[BELOW]= BUNDLE_HEAD; + } + } + } + else + { + if (edge->top.y == yt) + edge->xt= edge->top.x; + else + edge->xt= edge->bot.x + edge->dx * (yt - edge->bot.y); + } + } + + if (scanbeam < sbt_entries) + { + /* === SCANBEAM INTERIOR PROCESSING ============================== */ + + build_intersection_table(&it, aet, dy); + + /* Process each node in the intersection table */ + for (intersect= it; intersect; intersect= intersect->next) + { + e0= intersect->ie[0]; + e1= intersect->ie[1]; + + /* Only generate output for contributing intersections */ + if ((e0->bundle[ABOVE][CLIP] || e0->bundle[ABOVE][SUBJ]) + && (e1->bundle[ABOVE][CLIP] || e1->bundle[ABOVE][SUBJ])) + { + p= e0->outp[ABOVE]; + q= e1->outp[ABOVE]; + ix= intersect->point.x; + iy= intersect->point.y + yb; + + in[CLIP]= ( e0->bundle[ABOVE][CLIP] && !e0->bside[CLIP]) + || ( e1->bundle[ABOVE][CLIP] && e1->bside[CLIP]) + || (!e0->bundle[ABOVE][CLIP] && !e1->bundle[ABOVE][CLIP] + && e0->bside[CLIP] && e1->bside[CLIP]); + in[SUBJ]= ( e0->bundle[ABOVE][SUBJ] && !e0->bside[SUBJ]) + || ( e1->bundle[ABOVE][SUBJ] && e1->bside[SUBJ]) + || (!e0->bundle[ABOVE][SUBJ] && !e1->bundle[ABOVE][SUBJ] + && e0->bside[SUBJ] && e1->bside[SUBJ]); + + /* Determine quadrant occupancies */ + switch (op) + { + case GPC_DIFF: + case GPC_INT: + tr= (in[CLIP]) + && (in[SUBJ]); + tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP]) + && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]); + br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP]) + && (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP]) + && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + break; + case GPC_XOR: + tr= (in[CLIP]) + ^ (in[SUBJ]); + tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP]) + ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]); + br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP]) + ^ (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP]) + ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + break; + case GPC_UNION: + tr= (in[CLIP]) + || (in[SUBJ]); + tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP]) + || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]); + br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP]) + || (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP]) + || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]); + break; + } + + vclass= tr + (tl << 1) + (br << 2) + (bl << 3); + + switch (vclass) + { + case EMN: + new_tristrip(&tlist, e1, ix, iy); + e0->outp[ABOVE]= e1->outp[ABOVE]; + break; + case ERI: + if (p) + { + P_EDGE(prev_edge, e0, ABOVE, px, iy); + VERTEX(prev_edge, ABOVE, LEFT, px, iy); + VERTEX(e0, ABOVE, RIGHT, ix, iy); + e1->outp[ABOVE]= e0->outp[ABOVE]; + e0->outp[ABOVE]= NULL; + } + break; + case ELI: + if (q) + { + N_EDGE(next_edge, e1, ABOVE, nx, iy); + VERTEX(e1, ABOVE, LEFT, ix, iy); + VERTEX(next_edge, ABOVE, RIGHT, nx, iy); + e0->outp[ABOVE]= e1->outp[ABOVE]; + e1->outp[ABOVE]= NULL; + } + break; + case EMX: + if (p && q) + { + VERTEX(e0, ABOVE, LEFT, ix, iy); + e0->outp[ABOVE]= NULL; + e1->outp[ABOVE]= NULL; + } + break; + case IMN: + P_EDGE(prev_edge, e0, ABOVE, px, iy); + VERTEX(prev_edge, ABOVE, LEFT, px, iy); + N_EDGE(next_edge, e1, ABOVE, nx, iy); + VERTEX(next_edge, ABOVE, RIGHT, nx, iy); + new_tristrip(&tlist, prev_edge, px, iy); + e1->outp[ABOVE]= prev_edge->outp[ABOVE]; + VERTEX(e1, ABOVE, RIGHT, ix, iy); + new_tristrip(&tlist, e0, ix, iy); + next_edge->outp[ABOVE]= e0->outp[ABOVE]; + VERTEX(next_edge, ABOVE, RIGHT, nx, iy); + break; + case ILI: + if (p) + { + VERTEX(e0, ABOVE, LEFT, ix, iy); + N_EDGE(next_edge, e1, ABOVE, nx, iy); + VERTEX(next_edge, ABOVE, RIGHT, nx, iy); + e1->outp[ABOVE]= e0->outp[ABOVE]; + e0->outp[ABOVE]= NULL; + } + break; + case IRI: + if (q) + { + VERTEX(e1, ABOVE, RIGHT, ix, iy); + P_EDGE(prev_edge, e0, ABOVE, px, iy); + VERTEX(prev_edge, ABOVE, LEFT, px, iy); + e0->outp[ABOVE]= e1->outp[ABOVE]; + e1->outp[ABOVE]= NULL; + } + break; + case IMX: + if (p && q) + { + VERTEX(e0, ABOVE, RIGHT, ix, iy); + VERTEX(e1, ABOVE, LEFT, ix, iy); + e0->outp[ABOVE]= NULL; + e1->outp[ABOVE]= NULL; + P_EDGE(prev_edge, e0, ABOVE, px, iy); + VERTEX(prev_edge, ABOVE, LEFT, px, iy); + new_tristrip(&tlist, prev_edge, px, iy); + N_EDGE(next_edge, e1, ABOVE, nx, iy); + VERTEX(next_edge, ABOVE, RIGHT, nx, iy); + next_edge->outp[ABOVE]= prev_edge->outp[ABOVE]; + VERTEX(next_edge, ABOVE, RIGHT, nx, iy); + } + break; + case IMM: + if (p && q) + { + VERTEX(e0, ABOVE, RIGHT, ix, iy); + VERTEX(e1, ABOVE, LEFT, ix, iy); + P_EDGE(prev_edge, e0, ABOVE, px, iy); + VERTEX(prev_edge, ABOVE, LEFT, px, iy); + new_tristrip(&tlist, prev_edge, px, iy); + N_EDGE(next_edge, e1, ABOVE, nx, iy); + VERTEX(next_edge, ABOVE, RIGHT, nx, iy); + e1->outp[ABOVE]= prev_edge->outp[ABOVE]; + VERTEX(e1, ABOVE, RIGHT, ix, iy); + new_tristrip(&tlist, e0, ix, iy); + next_edge->outp[ABOVE]= e0->outp[ABOVE]; + VERTEX(next_edge, ABOVE, RIGHT, nx, iy); + } + break; + case EMM: + if (p && q) + { + VERTEX(e0, ABOVE, LEFT, ix, iy); + new_tristrip(&tlist, e1, ix, iy); + e0->outp[ABOVE]= e1->outp[ABOVE]; + } + break; + default: + break; + } /* End of switch */ + } /* End of contributing intersection conditional */ + + /* Swap bundle sides in response to edge crossing */ + if (e0->bundle[ABOVE][CLIP]) + e1->bside[CLIP]= !e1->bside[CLIP]; + if (e1->bundle[ABOVE][CLIP]) + e0->bside[CLIP]= !e0->bside[CLIP]; + if (e0->bundle[ABOVE][SUBJ]) + e1->bside[SUBJ]= !e1->bside[SUBJ]; + if (e1->bundle[ABOVE][SUBJ]) + e0->bside[SUBJ]= !e0->bside[SUBJ]; + + /* Swap e0 and e1 bundles in the AET */ + prev_edge= e0->prev; + next_edge= e1->next; + if (e1->next) + e1->next->prev= e0; + + if (e0->bstate[ABOVE] == BUNDLE_HEAD) + { + search= TRUE; + while (search) + { + prev_edge= prev_edge->prev; + if (prev_edge) + { + if (prev_edge->bundle[ABOVE][CLIP] + || prev_edge->bundle[ABOVE][SUBJ] + || (prev_edge->bstate[ABOVE] == BUNDLE_HEAD)) + search= FALSE; + } + else + search= FALSE; + } + } + if (!prev_edge) + { + e1->next= aet; + aet= e0->next; + } + else + { + e1->next= prev_edge->next; + prev_edge->next= e0->next; + } + e0->next->prev= prev_edge; + e1->next->prev= e1; + e0->next= next_edge; + } /* End of IT loop*/ + + /* Prepare for next scanbeam */ + for (edge= aet; edge; edge= next_edge) + { + next_edge= edge->next; + succ_edge= edge->succ; + + if ((edge->top.y == yt) && succ_edge) + { + /* Replace AET edge by its successor */ + succ_edge->outp[BELOW]= edge->outp[ABOVE]; + succ_edge->bstate[BELOW]= edge->bstate[ABOVE]; + succ_edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP]; + succ_edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ]; + prev_edge= edge->prev; + if (prev_edge) + prev_edge->next= succ_edge; + else + aet= succ_edge; + if (next_edge) + next_edge->prev= succ_edge; + succ_edge->prev= prev_edge; + succ_edge->next= next_edge; + } + else + { + /* Update this edge */ + edge->outp[BELOW]= edge->outp[ABOVE]; + edge->bstate[BELOW]= edge->bstate[ABOVE]; + edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP]; + edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ]; + edge->xb= edge->xt; + } + edge->outp[ABOVE]= NULL; + } + } + } /* === END OF SCANBEAM PROCESSING ================================== */ + + /* Generate result tristrip from tlist */ + result->strip= NULL; + result->num_strips= count_tristrips(tlist); + if (result->num_strips > 0) + { + MALLOC(result->strip, result->num_strips * sizeof(gpc_vertex_list), + "tristrip list creation", gpc_vertex_list); + + s= 0; + for (tn= tlist; tn; tn= tnn) + { + tnn= tn->next; + + if (tn->active > 2) + { + /* Valid tristrip: copy the vertices and free the heap */ + result->strip[s].num_vertices= tn->active; + MALLOC(result->strip[s].vertex, tn->active * sizeof(gpc_vertex), + "tristrip creation", gpc_vertex); + v= 0; + if (INVERT_TRISTRIPS) + { + lt= tn->v[RIGHT]; + rt= tn->v[LEFT]; + } + else + { + lt= tn->v[LEFT]; + rt= tn->v[RIGHT]; + } + while (lt || rt) + { + if (lt) + { + ltn= lt->next; + result->strip[s].vertex[v].x= lt->x; + result->strip[s].vertex[v].y= lt->y; + v++; + FREE(lt); + lt= ltn; + } + if (rt) + { + rtn= rt->next; + result->strip[s].vertex[v].x= rt->x; + result->strip[s].vertex[v].y= rt->y; + v++; + FREE(rt); + rt= rtn; + } + } + s++; + } + else + { + /* Invalid tristrip: just free the heap */ + for (lt= tn->v[LEFT]; lt; lt= ltn) + { + ltn= lt->next; + FREE(lt); + } + for (rt= tn->v[RIGHT]; rt; rt=rtn) + { + rtn= rt->next; + FREE(rt); + } + } + FREE(tn); + } + } + + /* Tidy up */ + reset_it(&it); + reset_lmt(&lmt); + FREE(c_heap); + FREE(s_heap); + FREE(sbt); +} + +/* +=========================================================================== + End of file: gpc.c +=========================================================================== +*/ diff --git a/gpc/gpc.h b/gpc/gpc.h new file mode 100644 index 0000000..ff00f7b --- /dev/null +++ b/gpc/gpc.h @@ -0,0 +1,133 @@ +/* +=========================================================================== + +Project: Generic Polygon Clipper + + A new algorithm for calculating the difference, intersection, + exclusive-or or union of arbitrary polygon sets. + +File: gpc.h +Author: Alan Murta (email: gpc@cs.man.ac.uk) +Version: 2.32 +Date: 17th December 2004 + +Copyright: (C) 1997-2004, Advanced Interfaces Group, + University of Manchester. + + This software is free for non-commercial use. It may be copied, + modified, and redistributed provided that this copyright notice + is preserved on all copies. The intellectual property rights of + the algorithms used reside with the University of Manchester + Advanced Interfaces Group. + + You may not use this software, in whole or in part, in support + of any commercial product without the express consent of the + author. + + There is no warranty or other guarantee of fitness of this + software for any purpose. It is provided solely "as is". + +=========================================================================== +*/ + +#ifndef __gpc_h +#define __gpc_h + +#include <stdio.h> + + +/* +=========================================================================== + Constants +=========================================================================== +*/ + +/* Increase GPC_EPSILON to encourage merging of near coincident edges */ + +#define GPC_EPSILON (DBL_EPSILON) + +#define GPC_VERSION "2.32" + + +/* +=========================================================================== + Public Data Types +=========================================================================== +*/ + +typedef enum /* Set operation type */ +{ + GPC_DIFF, /* Difference */ + GPC_INT, /* Intersection */ + GPC_XOR, /* Exclusive or */ + GPC_UNION /* Union */ +} gpc_op; + +typedef struct /* Polygon vertex structure */ +{ + double x; /* Vertex x component */ + double y; /* vertex y component */ +} gpc_vertex; + +typedef struct /* Vertex list structure */ +{ + int num_vertices; /* Number of vertices in list */ + gpc_vertex *vertex; /* Vertex array pointer */ +} gpc_vertex_list; + +typedef struct /* Polygon set structure */ +{ + int num_contours; /* Number of contours in polygon */ + int *hole; /* Hole / external contour flags */ + gpc_vertex_list *contour; /* Contour array pointer */ +} gpc_polygon; + +typedef struct /* Tristrip set structure */ +{ + int num_strips; /* Number of tristrips */ + gpc_vertex_list *strip; /* Tristrip array pointer */ +} gpc_tristrip; + + +/* +=========================================================================== + Public Function Prototypes +=========================================================================== +*/ + +void gpc_read_polygon (FILE *infile_ptr, + int read_hole_flags, + gpc_polygon *polygon); + +void gpc_write_polygon (FILE *outfile_ptr, + int write_hole_flags, + gpc_polygon *polygon); + +void gpc_add_contour (gpc_polygon *polygon, + gpc_vertex_list *contour, + int hole); + +void gpc_polygon_clip (gpc_op set_operation, + gpc_polygon *subject_polygon, + gpc_polygon *clip_polygon, + gpc_polygon *result_polygon); + +void gpc_tristrip_clip (gpc_op set_operation, + gpc_polygon *subject_polygon, + gpc_polygon *clip_polygon, + gpc_tristrip *result_tristrip); + +void gpc_polygon_to_tristrip (gpc_polygon *polygon, + gpc_tristrip *tristrip); + +void gpc_free_polygon (gpc_polygon *polygon); + +void gpc_free_tristrip (gpc_tristrip *tristrip); + +#endif + +/* +=========================================================================== + End of file: gpc.h +=========================================================================== +*/ diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..6399aed --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,49 @@ +SUBDIRS = ctrl util platform + +aggincludedir = $(includedir)/agg2 +agginclude_HEADERS = \ + agg_alpha_mask_u8.h agg_glyph_raster_bin.h agg_span_allocator.h \ + agg_arc.h agg_gsv_text.h agg_span_converter.h \ + agg_array.h agg_image_accessors.h agg_span_gouraud.h \ + agg_arrowhead.h agg_image_filters.h agg_span_gouraud_gray.h \ + agg_basics.h agg_line_aa_basics.h agg_span_gouraud_rgba.h \ + agg_bezier_arc.h agg_math.h agg_span_gradient.h \ + agg_bitset_iterator.h agg_blur.h agg_math_stroke.h \ + agg_span_gradient_alpha.h agg_gradient_lut.h \ + agg_bounding_rect.h agg_path_length.h agg_span_image_filter.h \ + agg_bspline.h agg_path_storage.h agg_span_image_filter_gray.h \ + agg_clip_liang_barsky.h agg_path_storage_integer.h agg_span_image_filter_rgb.h \ + agg_color_gray.h agg_pattern_filters_rgba.h agg_span_image_filter_rgba.h \ + agg_color_rgba.h agg_pixfmt_amask_adaptor.h agg_span_interpolator_adaptor.h \ + agg_config.h agg_pixfmt_gray.h agg_span_interpolator_linear.h \ + agg_conv_adaptor_vcgen.h agg_pixfmt_rgb.h agg_span_interpolator_persp.h \ + agg_conv_adaptor_vpgen.h agg_pixfmt_rgb_packed.h agg_span_interpolator_trans.h \ + agg_conv_bspline.h agg_pixfmt_rgba.h agg_pixfmt_transposer.h \ + agg_span_pattern_gray.h \ + agg_conv_clip_polygon.h agg_rasterizer_cells_aa.h agg_span_pattern_rgb.h \ + agg_conv_clip_polyline.h agg_rasterizer_compound_aa.h agg_span_pattern_rgba.h \ + agg_conv_close_polygon.h agg_rasterizer_outline.h agg_span_solid.h \ + agg_conv_concat.h agg_rasterizer_outline_aa.h agg_span_subdiv_adaptor.h \ + agg_conv_contour.h agg_rasterizer_scanline_aa.h agg_trans_affine.h \ + agg_conv_curve.h agg_rasterizer_sl_clip.h agg_trans_bilinear.h \ + agg_conv_dash.h agg_renderer_base.h agg_trans_double_path.h \ + agg_conv_gpc.h agg_renderer_markers.h \ + agg_conv_marker.h agg_renderer_mclip.h agg_trans_perspective.h \ + agg_conv_marker_adaptor.h agg_renderer_outline_aa.h agg_trans_single_path.h \ + agg_conv_segmentator.h agg_renderer_outline_image.h agg_trans_viewport.h \ + agg_conv_shorten_path.h agg_renderer_primitives.h agg_trans_warp_magnifier.h \ + agg_conv_smooth_poly1.h agg_renderer_raster_text.h agg_vcgen_bspline.h \ + agg_conv_stroke.h agg_renderer_scanline.h agg_vcgen_contour.h \ + agg_conv_transform.h agg_rendering_buffer.h agg_vcgen_dash.h \ + agg_conv_unclose_polygon.h agg_rendering_buffer_dynarow.h agg_vcgen_markers_term.h \ + agg_curves.h agg_rounded_rect.h agg_vcgen_smooth_poly1.h \ + agg_scanline_bin.h agg_vcgen_stroke.h \ + agg_dda_line.h agg_scanline_boolean_algebra.h agg_vcgen_vertex_sequence.h \ + agg_ellipse.h agg_scanline_p.h agg_vertex_sequence.h \ + agg_ellipse_bresenham.h agg_scanline_storage_aa.h agg_vpgen_clip_polygon.h \ + agg_embedded_raster_fonts.h agg_scanline_storage_bin.h agg_vpgen_clip_polyline.h \ + agg_font_cache_manager.h agg_scanline_u.h agg_vpgen_segmentator.h \ + agg_gamma_functions.h agg_shorten_path.h \ + agg_gamma_lut.h agg_simul_eq.h \ + agg_font_cache_manager2.h agg_pixfmt_base.h agg_rasterizer_scanline_aa_nogamma.h \ + agg_span_gradient_contour.h agg_span_gradient_image.h diff --git a/include/agg_alpha_mask_u8.h b/include/agg_alpha_mask_u8.h new file mode 100644 index 0000000..997d2c5 --- /dev/null +++ b/include/agg_alpha_mask_u8.h @@ -0,0 +1,499 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// scanline_u8 class +// +//---------------------------------------------------------------------------- +#ifndef AGG_ALPHA_MASK_U8_INCLUDED +#define AGG_ALPHA_MASK_U8_INCLUDED + +#include <cstring> +#include "agg_basics.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + //===================================================one_component_mask_u8 + struct one_component_mask_u8 + { + static unsigned calculate(const int8u* p) { return *p; } + }; + + + //=====================================================rgb_to_gray_mask_u8 + template<unsigned R, unsigned G, unsigned B> + struct rgb_to_gray_mask_u8 + { + static unsigned calculate(const int8u* p) + { + return (p[R]*77 + p[G]*150 + p[B]*29) >> 8; + } + }; + + //==========================================================alpha_mask_u8 + template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8> + class alpha_mask_u8 + { + public: + typedef int8u cover_type; + typedef alpha_mask_u8<Step, Offset, MaskF> self_type; + enum cover_scale_e + { + cover_shift = 8, + cover_none = 0, + cover_full = 255 + }; + + alpha_mask_u8() : m_rbuf(0) {} + explicit alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {} + + void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; } + + MaskF& mask_function() { return m_mask_function; } + const MaskF& mask_function() const { return m_mask_function; } + + + //-------------------------------------------------------------------- + cover_type pixel(int x, int y) const + { + if(x >= 0 && y >= 0 && + x < (int)m_rbuf->width() && + y < (int)m_rbuf->height()) + { + return (cover_type)m_mask_function.calculate( + m_rbuf->row_ptr(y) + x * Step + Offset); + } + return 0; + } + + //-------------------------------------------------------------------- + cover_type combine_pixel(int x, int y, cover_type val) const + { + if(x >= 0 && y >= 0 && + x < (int)m_rbuf->width() && + y < (int)m_rbuf->height()) + { + return (cover_type)((cover_full + val * + m_mask_function.calculate( + m_rbuf->row_ptr(y) + x * Step + Offset)) >> + cover_shift); + } + return 0; + } + + + //-------------------------------------------------------------------- + void fill_hspan(int x, int y, cover_type* dst, int num_pix) const + { + int xmax = m_rbuf->width() - 1; + int ymax = m_rbuf->height() - 1; + + int count = num_pix; + cover_type* covers = dst; + + if(y < 0 || y > ymax) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + + if(x < 0) + { + count += x; + if(count <= 0) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + std::memset(covers, 0, -x * sizeof(cover_type)); + covers -= x; + x = 0; + } + + if(x + count > xmax) + { + int rest = x + count - xmax - 1; + count -= rest; + if(count <= 0) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + std::memset(covers + count, 0, rest * sizeof(cover_type)); + } + + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *covers++ = (cover_type)m_mask_function.calculate(mask); + mask += Step; + } + while(--count); + } + + + //-------------------------------------------------------------------- + void combine_hspan(int x, int y, cover_type* dst, int num_pix) const + { + int xmax = m_rbuf->width() - 1; + int ymax = m_rbuf->height() - 1; + + int count = num_pix; + cover_type* covers = dst; + + if(y < 0 || y > ymax) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + + if(x < 0) + { + count += x; + if(count <= 0) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + std::memset(covers, 0, -x * sizeof(cover_type)); + covers -= x; + x = 0; + } + + if(x + count > xmax) + { + int rest = x + count - xmax - 1; + count -= rest; + if(count <= 0) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + std::memset(covers + count, 0, rest * sizeof(cover_type)); + } + + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *covers = (cover_type)((cover_full + (*covers) * + m_mask_function.calculate(mask)) >> + cover_shift); + ++covers; + mask += Step; + } + while(--count); + } + + //-------------------------------------------------------------------- + void fill_vspan(int x, int y, cover_type* dst, int num_pix) const + { + int xmax = m_rbuf->width() - 1; + int ymax = m_rbuf->height() - 1; + + int count = num_pix; + cover_type* covers = dst; + + if(x < 0 || x > xmax) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + + if(y < 0) + { + count += y; + if(count <= 0) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + std::memset(covers, 0, -y * sizeof(cover_type)); + covers -= y; + y = 0; + } + + if(y + count > ymax) + { + int rest = y + count - ymax - 1; + count -= rest; + if(count <= 0) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + std::memset(covers + count, 0, rest * sizeof(cover_type)); + } + + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *covers++ = (cover_type)m_mask_function.calculate(mask); + mask += m_rbuf->stride(); + } + while(--count); + } + + //-------------------------------------------------------------------- + void combine_vspan(int x, int y, cover_type* dst, int num_pix) const + { + int xmax = m_rbuf->width() - 1; + int ymax = m_rbuf->height() - 1; + + int count = num_pix; + cover_type* covers = dst; + + if(x < 0 || x > xmax) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + + if(y < 0) + { + count += y; + if(count <= 0) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + std::memset(covers, 0, -y * sizeof(cover_type)); + covers -= y; + y = 0; + } + + if(y + count > ymax) + { + int rest = y + count - ymax - 1; + count -= rest; + if(count <= 0) + { + std::memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + std::memset(covers + count, 0, rest * sizeof(cover_type)); + } + + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *covers = (cover_type)((cover_full + (*covers) * + m_mask_function.calculate(mask)) >> + cover_shift); + ++covers; + mask += m_rbuf->stride(); + } + while(--count); + } + + + private: + alpha_mask_u8(const self_type&); + const self_type& operator = (const self_type&); + + rendering_buffer* m_rbuf; + MaskF m_mask_function; + }; + + + typedef alpha_mask_u8<1, 0> alpha_mask_gray8; //----alpha_mask_gray8 + + typedef alpha_mask_u8<3, 0> alpha_mask_rgb24r; //----alpha_mask_rgb24r + typedef alpha_mask_u8<3, 1> alpha_mask_rgb24g; //----alpha_mask_rgb24g + typedef alpha_mask_u8<3, 2> alpha_mask_rgb24b; //----alpha_mask_rgb24b + + typedef alpha_mask_u8<3, 2> alpha_mask_bgr24r; //----alpha_mask_bgr24r + typedef alpha_mask_u8<3, 1> alpha_mask_bgr24g; //----alpha_mask_bgr24g + typedef alpha_mask_u8<3, 0> alpha_mask_bgr24b; //----alpha_mask_bgr24b + + typedef alpha_mask_u8<4, 0> alpha_mask_rgba32r; //----alpha_mask_rgba32r + typedef alpha_mask_u8<4, 1> alpha_mask_rgba32g; //----alpha_mask_rgba32g + typedef alpha_mask_u8<4, 2> alpha_mask_rgba32b; //----alpha_mask_rgba32b + typedef alpha_mask_u8<4, 3> alpha_mask_rgba32a; //----alpha_mask_rgba32a + + typedef alpha_mask_u8<4, 1> alpha_mask_argb32r; //----alpha_mask_argb32r + typedef alpha_mask_u8<4, 2> alpha_mask_argb32g; //----alpha_mask_argb32g + typedef alpha_mask_u8<4, 3> alpha_mask_argb32b; //----alpha_mask_argb32b + typedef alpha_mask_u8<4, 0> alpha_mask_argb32a; //----alpha_mask_argb32a + + typedef alpha_mask_u8<4, 2> alpha_mask_bgra32r; //----alpha_mask_bgra32r + typedef alpha_mask_u8<4, 1> alpha_mask_bgra32g; //----alpha_mask_bgra32g + typedef alpha_mask_u8<4, 0> alpha_mask_bgra32b; //----alpha_mask_bgra32b + typedef alpha_mask_u8<4, 3> alpha_mask_bgra32a; //----alpha_mask_bgra32a + + typedef alpha_mask_u8<4, 3> alpha_mask_abgr32r; //----alpha_mask_abgr32r + typedef alpha_mask_u8<4, 2> alpha_mask_abgr32g; //----alpha_mask_abgr32g + typedef alpha_mask_u8<4, 1> alpha_mask_abgr32b; //----alpha_mask_abgr32b + typedef alpha_mask_u8<4, 0> alpha_mask_abgr32a; //----alpha_mask_abgr32a + + typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgb24gray; //----alpha_mask_rgb24gray + typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgr24gray; //----alpha_mask_bgr24gray + typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgba32gray; //----alpha_mask_rgba32gray + typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_argb32gray; //----alpha_mask_argb32gray + typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgra32gray; //----alpha_mask_bgra32gray + typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_abgr32gray; //----alpha_mask_abgr32gray + + + + //==========================================================amask_no_clip_u8 + template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8> + class amask_no_clip_u8 + { + public: + typedef int8u cover_type; + typedef amask_no_clip_u8<Step, Offset, MaskF> self_type; + enum cover_scale_e + { + cover_shift = 8, + cover_none = 0, + cover_full = 255 + }; + + amask_no_clip_u8() : m_rbuf(0) {} + explicit amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {} + + void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; } + + MaskF& mask_function() { return m_mask_function; } + const MaskF& mask_function() const { return m_mask_function; } + + + //-------------------------------------------------------------------- + cover_type pixel(int x, int y) const + { + return (cover_type)m_mask_function.calculate( + m_rbuf->row_ptr(y) + x * Step + Offset); + } + + + //-------------------------------------------------------------------- + cover_type combine_pixel(int x, int y, cover_type val) const + { + return (cover_type)((cover_full + val * + m_mask_function.calculate( + m_rbuf->row_ptr(y) + x * Step + Offset)) >> + cover_shift); + } + + + //-------------------------------------------------------------------- + void fill_hspan(int x, int y, cover_type* dst, int num_pix) const + { + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *dst++ = (cover_type)m_mask_function.calculate(mask); + mask += Step; + } + while(--num_pix); + } + + + + //-------------------------------------------------------------------- + void combine_hspan(int x, int y, cover_type* dst, int num_pix) const + { + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *dst = (cover_type)((cover_full + (*dst) * + m_mask_function.calculate(mask)) >> + cover_shift); + ++dst; + mask += Step; + } + while(--num_pix); + } + + + //-------------------------------------------------------------------- + void fill_vspan(int x, int y, cover_type* dst, int num_pix) const + { + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *dst++ = (cover_type)m_mask_function.calculate(mask); + mask += m_rbuf->stride(); + } + while(--num_pix); + } + + + //-------------------------------------------------------------------- + void combine_vspan(int x, int y, cover_type* dst, int num_pix) const + { + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *dst = (cover_type)((cover_full + (*dst) * + m_mask_function.calculate(mask)) >> + cover_shift); + ++dst; + mask += m_rbuf->stride(); + } + while(--num_pix); + } + + private: + amask_no_clip_u8(const self_type&); + const self_type& operator = (const self_type&); + + rendering_buffer* m_rbuf; + MaskF m_mask_function; + }; + + + typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8 + + typedef amask_no_clip_u8<3, 0> amask_no_clip_rgb24r; //----amask_no_clip_rgb24r + typedef amask_no_clip_u8<3, 1> amask_no_clip_rgb24g; //----amask_no_clip_rgb24g + typedef amask_no_clip_u8<3, 2> amask_no_clip_rgb24b; //----amask_no_clip_rgb24b + + typedef amask_no_clip_u8<3, 2> amask_no_clip_bgr24r; //----amask_no_clip_bgr24r + typedef amask_no_clip_u8<3, 1> amask_no_clip_bgr24g; //----amask_no_clip_bgr24g + typedef amask_no_clip_u8<3, 0> amask_no_clip_bgr24b; //----amask_no_clip_bgr24b + + typedef amask_no_clip_u8<4, 0> amask_no_clip_rgba32r; //----amask_no_clip_rgba32r + typedef amask_no_clip_u8<4, 1> amask_no_clip_rgba32g; //----amask_no_clip_rgba32g + typedef amask_no_clip_u8<4, 2> amask_no_clip_rgba32b; //----amask_no_clip_rgba32b + typedef amask_no_clip_u8<4, 3> amask_no_clip_rgba32a; //----amask_no_clip_rgba32a + + typedef amask_no_clip_u8<4, 1> amask_no_clip_argb32r; //----amask_no_clip_argb32r + typedef amask_no_clip_u8<4, 2> amask_no_clip_argb32g; //----amask_no_clip_argb32g + typedef amask_no_clip_u8<4, 3> amask_no_clip_argb32b; //----amask_no_clip_argb32b + typedef amask_no_clip_u8<4, 0> amask_no_clip_argb32a; //----amask_no_clip_argb32a + + typedef amask_no_clip_u8<4, 2> amask_no_clip_bgra32r; //----amask_no_clip_bgra32r + typedef amask_no_clip_u8<4, 1> amask_no_clip_bgra32g; //----amask_no_clip_bgra32g + typedef amask_no_clip_u8<4, 0> amask_no_clip_bgra32b; //----amask_no_clip_bgra32b + typedef amask_no_clip_u8<4, 3> amask_no_clip_bgra32a; //----amask_no_clip_bgra32a + + typedef amask_no_clip_u8<4, 3> amask_no_clip_abgr32r; //----amask_no_clip_abgr32r + typedef amask_no_clip_u8<4, 2> amask_no_clip_abgr32g; //----amask_no_clip_abgr32g + typedef amask_no_clip_u8<4, 1> amask_no_clip_abgr32b; //----amask_no_clip_abgr32b + typedef amask_no_clip_u8<4, 0> amask_no_clip_abgr32a; //----amask_no_clip_abgr32a + + typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgb24gray; //----amask_no_clip_rgb24gray + typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgr24gray; //----amask_no_clip_bgr24gray + typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgba32gray; //----amask_no_clip_rgba32gray + typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_argb32gray; //----amask_no_clip_argb32gray + typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgra32gray; //----amask_no_clip_bgra32gray + typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_abgr32gray; //----amask_no_clip_abgr32gray + + +} + + + +#endif diff --git a/include/agg_arc.h b/include/agg_arc.h new file mode 100644 index 0000000..56ac487 --- /dev/null +++ b/include/agg_arc.h @@ -0,0 +1,73 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Arc vertex generator +// +//---------------------------------------------------------------------------- + +#ifndef AGG_ARC_INCLUDED +#define AGG_ARC_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //=====================================================================arc + // + // See Implementation agg_arc.cpp + // + class arc + { + public: + arc() : m_scale(1.0), m_initialized(false) {} + arc(double x, double y, + double rx, double ry, + double a1, double a2, + bool ccw=true); + + void init(double x, double y, + double rx, double ry, + double a1, double a2, + bool ccw=true); + + void approximation_scale(double s); + double approximation_scale() const { return m_scale; } + + void rewind(unsigned); + unsigned vertex(double* x, double* y); + + private: + void normalize(double a1, double a2, bool ccw); + + double m_x; + double m_y; + double m_rx; + double m_ry; + double m_angle; + double m_start; + double m_end; + double m_scale; + double m_da; + bool m_ccw; + bool m_initialized; + unsigned m_path_cmd; + }; + + +} + + +#endif diff --git a/include/agg_array.h b/include/agg_array.h new file mode 100644 index 0000000..b48010b --- /dev/null +++ b/include/agg_array.h @@ -0,0 +1,1119 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_ARRAY_INCLUDED +#define AGG_ARRAY_INCLUDED + +#include <cstddef> +#include <cstring> +#include "agg_basics.h" + +namespace agg +{ + + //-------------------------------------------------------pod_array_adaptor + template<class T> class pod_array_adaptor + { + public: + typedef T value_type; + pod_array_adaptor(T* array, unsigned size) : + m_array(array), m_size(size) {} + + unsigned size() const { return m_size; } + const T& operator [] (unsigned i) const { return m_array[i]; } + T& operator [] (unsigned i) { return m_array[i]; } + const T& at(unsigned i) const { return m_array[i]; } + T& at(unsigned i) { return m_array[i]; } + T value_at(unsigned i) const { return m_array[i]; } + + private: + T* m_array; + unsigned m_size; + }; + + + //---------------------------------------------------------pod_auto_array + template<class T, unsigned Size> class pod_auto_array + { + public: + typedef T value_type; + typedef pod_auto_array<T, Size> self_type; + + pod_auto_array() {} + explicit pod_auto_array(const T* c) + { + std::memcpy(m_array, c, sizeof(T) * Size); + } + + const self_type& operator = (const T* c) + { + std::memcpy(m_array, c, sizeof(T) * Size); + return *this; + } + + static unsigned size() { return Size; } + const T& operator [] (unsigned i) const { return m_array[i]; } + T& operator [] (unsigned i) { return m_array[i]; } + const T& at(unsigned i) const { return m_array[i]; } + T& at(unsigned i) { return m_array[i]; } + T value_at(unsigned i) const { return m_array[i]; } + + private: + T m_array[Size]; + }; + + + //--------------------------------------------------------pod_auto_vector + template<class T, unsigned Size> class pod_auto_vector + { + public: + typedef T value_type; + typedef pod_auto_vector<T, Size> self_type; + + pod_auto_vector() : m_size(0) {} + + void remove_all() { m_size = 0; } + void clear() { m_size = 0; } + void add(const T& v) { m_array[m_size++] = v; } + void push_back(const T& v) { m_array[m_size++] = v; } + void inc_size(unsigned size) { m_size += size; } + + unsigned size() const { return m_size; } + const T& operator [] (unsigned i) const { return m_array[i]; } + T& operator [] (unsigned i) { return m_array[i]; } + const T& at(unsigned i) const { return m_array[i]; } + T& at(unsigned i) { return m_array[i]; } + T value_at(unsigned i) const { return m_array[i]; } + + private: + T m_array[Size]; + unsigned m_size; + }; + + + //---------------------------------------------------------------pod_array + template<class T> class pod_array + { + public: + typedef T value_type; + typedef pod_array<T> self_type; + + ~pod_array() { pod_allocator<T>::deallocate(m_array, m_size); } + pod_array() : m_array(0), m_size(0) {} + + pod_array(unsigned size) : + m_array(pod_allocator<T>::allocate(size)), + m_size(size) + {} + + pod_array(const self_type& v) : + m_array(pod_allocator<T>::allocate(v.m_size)), + m_size(v.m_size) + { + std::memcpy(m_array, v.m_array, sizeof(T) * m_size); + } + + void resize(unsigned size) + { + if(size != m_size) + { + pod_allocator<T>::deallocate(m_array, m_size); + m_array = pod_allocator<T>::allocate(m_size = size); + } + } + const self_type& operator = (const self_type& v) + { + resize(v.size()); + std::memcpy(m_array, v.m_array, sizeof(T) * m_size); + return *this; + } + + unsigned size() const { return m_size; } + const T& operator [] (unsigned i) const { return m_array[i]; } + T& operator [] (unsigned i) { return m_array[i]; } + const T& at(unsigned i) const { return m_array[i]; } + T& at(unsigned i) { return m_array[i]; } + T value_at(unsigned i) const { return m_array[i]; } + + const T* data() const { return m_array; } + T* data() { return m_array; } + private: + T* m_array; + unsigned m_size; + }; + + + + //--------------------------------------------------------------pod_vector + // A simple class template to store Plain Old Data, a vector + // of a fixed size. The data is continous in memory + //------------------------------------------------------------------------ + template<class T> class pod_vector + { + public: + typedef T value_type; + + ~pod_vector() { pod_allocator<T>::deallocate(m_array, m_capacity); } + pod_vector() : m_size(0), m_capacity(0), m_array(0) {} + pod_vector(unsigned cap, unsigned extra_tail=0); + + // Copying + pod_vector(const pod_vector<T>&); + const pod_vector<T>& operator = (const pod_vector<T>&); + + // Set new capacity. All data is lost, size is set to zero. + void capacity(unsigned cap, unsigned extra_tail=0); + unsigned capacity() const { return m_capacity; } + + // Allocate n elements. All data is lost, + // but elements can be accessed in range 0...size-1. + void allocate(unsigned size, unsigned extra_tail=0); + + // Resize keeping the content. + void resize(unsigned new_size); + + void zero() + { + std::memset(m_array, 0, sizeof(T) * m_size); + } + + void add(const T& v) { m_array[m_size++] = v; } + void push_back(const T& v) { m_array[m_size++] = v; } + void insert_at(unsigned pos, const T& val); + void inc_size(unsigned size) { m_size += size; } + unsigned size() const { return m_size; } + unsigned byte_size() const { return m_size * sizeof(T); } + void serialize(int8u* ptr) const; + void deserialize(const int8u* data, unsigned byte_size); + const T& operator [] (unsigned i) const { return m_array[i]; } + T& operator [] (unsigned i) { return m_array[i]; } + const T& at(unsigned i) const { return m_array[i]; } + T& at(unsigned i) { return m_array[i]; } + T value_at(unsigned i) const { return m_array[i]; } + + const T* data() const { return m_array; } + T* data() { return m_array; } + + void remove_all() { m_size = 0; } + void clear() { m_size = 0; } + void cut_at(unsigned num) { if(num < m_size) m_size = num; } + + private: + unsigned m_size; + unsigned m_capacity; + T* m_array; + }; + + //------------------------------------------------------------------------ + template<class T> + void pod_vector<T>::capacity(unsigned cap, unsigned extra_tail) + { + m_size = 0; + if(cap > m_capacity) + { + pod_allocator<T>::deallocate(m_array, m_capacity); + m_capacity = cap + extra_tail; + m_array = m_capacity ? pod_allocator<T>::allocate(m_capacity) : 0; + } + } + + //------------------------------------------------------------------------ + template<class T> + void pod_vector<T>::allocate(unsigned size, unsigned extra_tail) + { + capacity(size, extra_tail); + m_size = size; + } + + + //------------------------------------------------------------------------ + template<class T> + void pod_vector<T>::resize(unsigned new_size) + { + if(new_size > m_size) + { + if(new_size > m_capacity) + { + T* data = pod_allocator<T>::allocate(new_size); + std::memcpy(data, m_array, m_size * sizeof(T)); + pod_allocator<T>::deallocate(m_array, m_capacity); + m_array = data; + } + } + else + { + m_size = new_size; + } + } + + //------------------------------------------------------------------------ + template<class T> pod_vector<T>::pod_vector(unsigned cap, unsigned extra_tail) : + m_size(0), + m_capacity(cap + extra_tail), + m_array(pod_allocator<T>::allocate(m_capacity)) {} + + //------------------------------------------------------------------------ + template<class T> pod_vector<T>::pod_vector(const pod_vector<T>& v) : + m_size(v.m_size), + m_capacity(v.m_capacity), + m_array(v.m_capacity ? pod_allocator<T>::allocate(v.m_capacity) : 0) + { + std::memcpy(m_array, v.m_array, sizeof(T) * v.m_size); + } + + //------------------------------------------------------------------------ + template<class T> const pod_vector<T>& + pod_vector<T>::operator = (const pod_vector<T>&v) + { + allocate(v.m_size); + if(v.m_size) std::memcpy(m_array, v.m_array, sizeof(T) * v.m_size); + return *this; + } + + //------------------------------------------------------------------------ + template<class T> void pod_vector<T>::serialize(int8u* ptr) const + { + if(m_size) std::memcpy(ptr, m_array, m_size * sizeof(T)); + } + + //------------------------------------------------------------------------ + template<class T> + void pod_vector<T>::deserialize(const int8u* data, unsigned byte_size) + { + byte_size /= sizeof(T); + allocate(byte_size); + if(byte_size) std::memcpy(m_array, data, byte_size * sizeof(T)); + } + + //------------------------------------------------------------------------ + template<class T> + void pod_vector<T>::insert_at(unsigned pos, const T& val) + { + if(pos >= m_size) + { + m_array[m_size] = val; + } + else + { + std::memmove(m_array + pos + 1, m_array + pos, (m_size - pos) * sizeof(T)); + m_array[pos] = val; + } + ++m_size; + } + + //---------------------------------------------------------------pod_bvector + // A simple class template to store Plain Old Data, similar to std::deque + // It doesn't reallocate memory but instead, uses blocks of data of size + // of (1 << S), that is, power of two. The data is NOT contiguous in memory, + // so the only valid access method is operator [] or curr(), prev(), next() + // + // There reallocs occure only when the pool of pointers to blocks needs + // to be extended (it happens very rarely). You can control the value + // of increment to reallocate the pointer buffer. See the second constructor. + // By default, the incremeent value equals (1 << S), i.e., the block size. + //------------------------------------------------------------------------ + template<class T, unsigned S=6> class pod_bvector + { + public: + enum block_scale_e + { + block_shift = S, + block_size = 1 << block_shift, + block_mask = block_size - 1 + }; + + typedef T value_type; + + ~pod_bvector(); + pod_bvector(); + pod_bvector(unsigned block_ptr_inc); + + // Copying + pod_bvector(const pod_bvector<T, S>& v); + const pod_bvector<T, S>& operator = (const pod_bvector<T, S>& v); + + void remove_all() { m_size = 0; } + void clear() { m_size = 0; } + void free_all() { free_tail(0); } + void free_tail(unsigned size); + void add(const T& val); + void push_back(const T& val) { add(val); } + void modify_last(const T& val); + void remove_last(); + + int allocate_continuous_block(unsigned num_elements); + + void add_array(const T* ptr, unsigned num_elem) + { + while(num_elem--) + { + add(*ptr++); + } + } + + template<class DataAccessor> void add_data(DataAccessor& data) + { + while(data.size()) + { + add(*data); + ++data; + } + } + + void cut_at(unsigned size) + { + if(size < m_size) m_size = size; + } + + unsigned size() const { return m_size; } + + const T& operator [] (unsigned i) const + { + return m_blocks[i >> block_shift][i & block_mask]; + } + + T& operator [] (unsigned i) + { + return m_blocks[i >> block_shift][i & block_mask]; + } + + const T& at(unsigned i) const + { + return m_blocks[i >> block_shift][i & block_mask]; + } + + T& at(unsigned i) + { + return m_blocks[i >> block_shift][i & block_mask]; + } + + T value_at(unsigned i) const + { + return m_blocks[i >> block_shift][i & block_mask]; + } + + const T& curr(unsigned idx) const + { + return (*this)[idx]; + } + + T& curr(unsigned idx) + { + return (*this)[idx]; + } + + const T& prev(unsigned idx) const + { + return (*this)[(idx + m_size - 1) % m_size]; + } + + T& prev(unsigned idx) + { + return (*this)[(idx + m_size - 1) % m_size]; + } + + const T& next(unsigned idx) const + { + return (*this)[(idx + 1) % m_size]; + } + + T& next(unsigned idx) + { + return (*this)[(idx + 1) % m_size]; + } + + const T& last() const + { + return (*this)[m_size - 1]; + } + + T& last() + { + return (*this)[m_size - 1]; + } + + unsigned byte_size() const; + void serialize(int8u* ptr) const; + void deserialize(const int8u* data, unsigned byte_size); + void deserialize(unsigned start, const T& empty_val, + const int8u* data, unsigned byte_size); + + template<class ByteAccessor> + void deserialize(ByteAccessor data) + { + remove_all(); + unsigned elem_size = data.size() / sizeof(T); + + for(unsigned i = 0; i < elem_size; ++i) + { + int8u* ptr = (int8u*)data_ptr(); + for(unsigned j = 0; j < sizeof(T); ++j) + { + *ptr++ = *data; + ++data; + } + ++m_size; + } + } + + template<class ByteAccessor> + void deserialize(unsigned start, const T& empty_val, ByteAccessor data) + { + while(m_size < start) + { + add(empty_val); + } + + unsigned elem_size = data.size() / sizeof(T); + for(unsigned i = 0; i < elem_size; ++i) + { + int8u* ptr; + if(start + i < m_size) + { + ptr = (int8u*)(&((*this)[start + i])); + } + else + { + ptr = (int8u*)data_ptr(); + ++m_size; + } + for(unsigned j = 0; j < sizeof(T); ++j) + { + *ptr++ = *data; + ++data; + } + } + } + + const T* block(unsigned nb) const { return m_blocks[nb]; } + + private: + void allocate_block(unsigned nb); + T* data_ptr(); + + unsigned m_size; + unsigned m_num_blocks; + unsigned m_max_blocks; + T** m_blocks; + unsigned m_block_ptr_inc; + }; + + + //------------------------------------------------------------------------ + template<class T, unsigned S> pod_bvector<T, S>::~pod_bvector() + { + if(m_num_blocks) + { + T** blk = m_blocks + m_num_blocks - 1; + while(m_num_blocks--) + { + pod_allocator<T>::deallocate(*blk, block_size); + --blk; + } + } + pod_allocator<T*>::deallocate(m_blocks, m_max_blocks); + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::free_tail(unsigned size) + { + if(size < m_size) + { + unsigned nb = (size + block_mask) >> block_shift; + while(m_num_blocks > nb) + { + pod_allocator<T>::deallocate(m_blocks[--m_num_blocks], block_size); + } + if(m_num_blocks == 0) + { + pod_allocator<T*>::deallocate(m_blocks, m_max_blocks); + m_blocks = 0; + m_max_blocks = 0; + } + m_size = size; + } + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> pod_bvector<T, S>::pod_bvector() : + m_size(0), + m_num_blocks(0), + m_max_blocks(0), + m_blocks(0), + m_block_ptr_inc(block_size) + { + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + pod_bvector<T, S>::pod_bvector(unsigned block_ptr_inc) : + m_size(0), + m_num_blocks(0), + m_max_blocks(0), + m_blocks(0), + m_block_ptr_inc(block_ptr_inc) + { + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + pod_bvector<T, S>::pod_bvector(const pod_bvector<T, S>& v) : + m_size(v.m_size), + m_num_blocks(v.m_num_blocks), + m_max_blocks(v.m_max_blocks), + m_blocks(v.m_max_blocks ? + pod_allocator<T*>::allocate(v.m_max_blocks) : + 0), + m_block_ptr_inc(v.m_block_ptr_inc) + { + unsigned i; + for(i = 0; i < v.m_num_blocks; ++i) + { + m_blocks[i] = pod_allocator<T>::allocate(block_size); + std::memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); + } + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + const pod_bvector<T, S>& + pod_bvector<T, S>::operator = (const pod_bvector<T, S>& v) + { + unsigned i; + for(i = m_num_blocks; i < v.m_num_blocks; ++i) + { + allocate_block(i); + } + for(i = 0; i < v.m_num_blocks; ++i) + { + std::memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); + } + m_size = v.m_size; + return *this; + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::allocate_block(unsigned nb) + { + if(nb >= m_max_blocks) + { + T** new_blocks = pod_allocator<T*>::allocate(m_max_blocks + m_block_ptr_inc); + + if(m_blocks) + { + std::memcpy(new_blocks, + m_blocks, + m_num_blocks * sizeof(T*)); + + pod_allocator<T*>::deallocate(m_blocks, m_max_blocks); + } + m_blocks = new_blocks; + m_max_blocks += m_block_ptr_inc; + } + m_blocks[nb] = pod_allocator<T>::allocate(block_size); + m_num_blocks++; + } + + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + inline T* pod_bvector<T, S>::data_ptr() + { + unsigned nb = m_size >> block_shift; + if(nb >= m_num_blocks) + { + allocate_block(nb); + } + return m_blocks[nb] + (m_size & block_mask); + } + + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + inline void pod_bvector<T, S>::add(const T& val) + { + *data_ptr() = val; + ++m_size; + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + inline void pod_bvector<T, S>::remove_last() + { + if(m_size) --m_size; + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::modify_last(const T& val) + { + remove_last(); + add(val); + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + int pod_bvector<T, S>::allocate_continuous_block(unsigned num_elements) + { + if(num_elements < block_size) + { + data_ptr(); // Allocate initial block if necessary + unsigned rest = block_size - (m_size & block_mask); + unsigned index; + if(num_elements <= rest) + { + // The rest of the block is good, we can use it + //----------------- + index = m_size; + m_size += num_elements; + return index; + } + + // New block + //--------------- + m_size += rest; + data_ptr(); + index = m_size; + m_size += num_elements; + return index; + } + return -1; // Impossible to allocate + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + unsigned pod_bvector<T, S>::byte_size() const + { + return m_size * sizeof(T); + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::serialize(int8u* ptr) const + { + unsigned i; + for(i = 0; i < m_size; i++) + { + std::memcpy(ptr, &(*this)[i], sizeof(T)); + ptr += sizeof(T); + } + } + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::deserialize(const int8u* data, unsigned byte_size) + { + remove_all(); + byte_size /= sizeof(T); + for(unsigned i = 0; i < byte_size; ++i) + { + T* ptr = data_ptr(); + std::memcpy(ptr, data, sizeof(T)); + ++m_size; + data += sizeof(T); + } + } + + + // Replace or add a number of elements starting from "start" position + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::deserialize(unsigned start, const T& empty_val, + const int8u* data, unsigned byte_size) + { + while(m_size < start) + { + add(empty_val); + } + + byte_size /= sizeof(T); + for(unsigned i = 0; i < byte_size; ++i) + { + if(start + i < m_size) + { + std::memcpy(&((*this)[start + i]), data, sizeof(T)); + } + else + { + T* ptr = data_ptr(); + std::memcpy(ptr, data, sizeof(T)); + ++m_size; + } + data += sizeof(T); + } + } + + + //---------------------------------------------------------block_allocator + // Allocator for arbitrary POD data. Most usable in different cache + // systems for efficient memory allocations. + // Memory is allocated with blocks of fixed size ("block_size" in + // the constructor). If required size exceeds the block size the allocator + // creates a new block of the required size. However, the most efficient + // use is when the average reqired size is much less than the block size. + //------------------------------------------------------------------------ + class block_allocator + { + struct block_type + { + int8u* data; + unsigned size; + }; + + public: + void remove_all() + { + if(m_num_blocks) + { + block_type* blk = m_blocks + m_num_blocks - 1; + while(m_num_blocks--) + { + pod_allocator<int8u>::deallocate(blk->data, blk->size); + --blk; + } + pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks); + } + m_num_blocks = 0; + m_max_blocks = 0; + m_blocks = 0; + m_buf_ptr = 0; + m_rest = 0; + } + + ~block_allocator() + { + remove_all(); + } + + block_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) : + m_block_size(block_size), + m_block_ptr_inc(block_ptr_inc), + m_num_blocks(0), + m_max_blocks(0), + m_blocks(0), + m_buf_ptr(0), + m_rest(0) + { + } + + + int8u* allocate(unsigned size, unsigned alignment=1) + { + if(size == 0) return 0; + if(size <= m_rest) + { + int8u* ptr = m_buf_ptr; + if(alignment > 1) + { + unsigned align = + (alignment - unsigned((std::size_t)ptr) % alignment) % alignment; + + size += align; + ptr += align; + if(size <= m_rest) + { + m_rest -= size; + m_buf_ptr += size; + return ptr; + } + allocate_block(size); + return allocate(size - align, alignment); + } + m_rest -= size; + m_buf_ptr += size; + return ptr; + } + allocate_block(size + alignment - 1); + return allocate(size, alignment); + } + + + private: + void allocate_block(unsigned size) + { + if(size < m_block_size) size = m_block_size; + if(m_num_blocks >= m_max_blocks) + { + block_type* new_blocks = + pod_allocator<block_type>::allocate(m_max_blocks + m_block_ptr_inc); + + if(m_blocks) + { + std::memcpy(new_blocks, + m_blocks, + m_num_blocks * sizeof(block_type)); + pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks); + } + m_blocks = new_blocks; + m_max_blocks += m_block_ptr_inc; + } + + m_blocks[m_num_blocks].size = size; + m_blocks[m_num_blocks].data = + m_buf_ptr = + pod_allocator<int8u>::allocate(size); + + m_num_blocks++; + m_rest = size; + } + + unsigned m_block_size; + unsigned m_block_ptr_inc; + unsigned m_num_blocks; + unsigned m_max_blocks; + block_type* m_blocks; + int8u* m_buf_ptr; + unsigned m_rest; + }; + + + + + + + + + //------------------------------------------------------------------------ + enum quick_sort_threshold_e + { + quick_sort_threshold = 9 + }; + + + //-----------------------------------------------------------swap_elements + template<class T> inline void swap_elements(T& a, T& b) + { + T temp = a; + a = b; + b = temp; + } + + + //--------------------------------------------------------------quick_sort + template<class Array, class Less> + void quick_sort(Array& arr, Less less) + { + if(arr.size() < 2) return; + + typename Array::value_type* e1; + typename Array::value_type* e2; + + int stack[80]; + int* top = stack; + int limit = arr.size(); + int base = 0; + + for(;;) + { + int len = limit - base; + + int i; + int j; + int pivot; + + if(len > quick_sort_threshold) + { + // we use base + len/2 as the pivot + pivot = base + len / 2; + swap_elements(arr[base], arr[pivot]); + + i = base + 1; + j = limit - 1; + + // now ensure that *i <= *base <= *j + e1 = &(arr[j]); + e2 = &(arr[i]); + if(less(*e1, *e2)) swap_elements(*e1, *e2); + + e1 = &(arr[base]); + e2 = &(arr[i]); + if(less(*e1, *e2)) swap_elements(*e1, *e2); + + e1 = &(arr[j]); + e2 = &(arr[base]); + if(less(*e1, *e2)) swap_elements(*e1, *e2); + + for(;;) + { + do i++; while( less(arr[i], arr[base]) ); + do j--; while( less(arr[base], arr[j]) ); + + if( i > j ) + { + break; + } + + swap_elements(arr[i], arr[j]); + } + + swap_elements(arr[base], arr[j]); + + // now, push the largest sub-array + if(j - base > limit - i) + { + top[0] = base; + top[1] = j; + base = i; + } + else + { + top[0] = i; + top[1] = limit; + limit = j; + } + top += 2; + } + else + { + // the sub-array is small, perform insertion sort + j = base; + i = j + 1; + + for(; i < limit; j = i, i++) + { + for(; less(*(e1 = &(arr[j + 1])), *(e2 = &(arr[j]))); j--) + { + swap_elements(*e1, *e2); + if(j == base) + { + break; + } + } + } + if(top > stack) + { + top -= 2; + base = top[0]; + limit = top[1]; + } + else + { + break; + } + } + } + } + + + + + //------------------------------------------------------remove_duplicates + // Remove duplicates from a sorted array. It doesn't cut the + // tail of the array, it just returns the number of remaining elements. + //----------------------------------------------------------------------- + template<class Array, class Equal> + unsigned remove_duplicates(Array& arr, Equal equal) + { + if(arr.size() < 2) return arr.size(); + + unsigned i, j; + for(i = 1, j = 1; i < arr.size(); i++) + { + typename Array::value_type& e = arr[i]; + if(!equal(e, arr[i - 1])) + { + arr[j++] = e; + } + } + return j; + } + + //--------------------------------------------------------invert_container + template<class Array> void invert_container(Array& arr) + { + int i = 0; + int j = arr.size() - 1; + while(i < j) + { + swap_elements(arr[i++], arr[j--]); + } + } + + //------------------------------------------------------binary_search_pos + template<class Array, class Value, class Less> + unsigned binary_search_pos(const Array& arr, const Value& val, Less less) + { + if(arr.size() == 0) return 0; + + unsigned beg = 0; + unsigned end = arr.size() - 1; + + if(less(val, arr[0])) return 0; + if(less(arr[end], val)) return end + 1; + + while(end - beg > 1) + { + unsigned mid = (end + beg) >> 1; + if(less(val, arr[mid])) end = mid; + else beg = mid; + } + + //if(beg <= 0 && less(val, arr[0])) return 0; + //if(end >= arr.size() - 1 && less(arr[end], val)) ++end; + + return end; + } + + //----------------------------------------------------------range_adaptor + template<class Array> class range_adaptor + { + public: + typedef typename Array::value_type value_type; + + range_adaptor(Array& array, unsigned start, unsigned size) : + m_array(array), m_start(start), m_size(size) + {} + + unsigned size() const { return m_size; } + const value_type& operator [] (unsigned i) const { return m_array[m_start + i]; } + value_type& operator [] (unsigned i) { return m_array[m_start + i]; } + const value_type& at(unsigned i) const { return m_array[m_start + i]; } + value_type& at(unsigned i) { return m_array[m_start + i]; } + value_type value_at(unsigned i) const { return m_array[m_start + i]; } + + private: + Array& m_array; + unsigned m_start; + unsigned m_size; + }; + + //---------------------------------------------------------------int_less + inline bool int_less(int a, int b) { return a < b; } + + //------------------------------------------------------------int_greater + inline bool int_greater(int a, int b) { return a > b; } + + //----------------------------------------------------------unsigned_less + inline bool unsigned_less(unsigned a, unsigned b) { return a < b; } + + //-------------------------------------------------------unsigned_greater + inline bool unsigned_greater(unsigned a, unsigned b) { return a > b; } +} + +#endif diff --git a/include/agg_arrowhead.h b/include/agg_arrowhead.h new file mode 100644 index 0000000..5e029dd --- /dev/null +++ b/include/agg_arrowhead.h @@ -0,0 +1,82 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Simple arrowhead/arrowtail generator +// +//---------------------------------------------------------------------------- +#ifndef AGG_ARROWHEAD_INCLUDED +#define AGG_ARROWHEAD_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //===============================================================arrowhead + // + // See implementation agg_arrowhead.cpp + // + class arrowhead + { + public: + arrowhead(); + + void head(double d1, double d2, double d3, double d4) + { + m_head_d1 = d1; + m_head_d2 = d2; + m_head_d3 = d3; + m_head_d4 = d4; + m_head_flag = true; + } + + void head() { m_head_flag = true; } + void no_head() { m_head_flag = false; } + + void tail(double d1, double d2, double d3, double d4) + { + m_tail_d1 = d1; + m_tail_d2 = d2; + m_tail_d3 = d3; + m_tail_d4 = d4; + m_tail_flag = true; + } + + void tail() { m_tail_flag = true; } + void no_tail() { m_tail_flag = false; } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + double m_head_d1; + double m_head_d2; + double m_head_d3; + double m_head_d4; + double m_tail_d1; + double m_tail_d2; + double m_tail_d3; + double m_tail_d4; + bool m_head_flag; + bool m_tail_flag; + double m_coord[16]; + unsigned m_cmd[8]; + unsigned m_curr_id; + unsigned m_curr_coord; + }; + +} + +#endif diff --git a/include/agg_basics.h b/include/agg_basics.h new file mode 100644 index 0000000..62364d1 --- /dev/null +++ b/include/agg_basics.h @@ -0,0 +1,574 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_BASICS_INCLUDED +#define AGG_BASICS_INCLUDED + +#include <cmath> +#include "agg_config.h" + +//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR +#ifdef AGG_CUSTOM_ALLOCATOR +#include "agg_allocator.h" +#else +namespace agg +{ + // The policy of all AGG containers and memory allocation strategy + // in general is that no allocated data requires explicit construction. + // It means that the allocator can be really simple; you can even + // replace new/delete to malloc/free. The constructors and destructors + // won't be called in this case, however everything will remain working. + // The second argument of deallocate() is the size of the allocated + // block. You can use this information if you wish. + //------------------------------------------------------------pod_allocator + template<class T> struct pod_allocator + { + static T* allocate(unsigned num) { return new T [num]; } + static void deallocate(T* ptr, unsigned) { delete [] ptr; } + }; + + // Single object allocator. It's also can be replaced with your custom + // allocator. The difference is that it can only allocate a single + // object and the constructor and destructor must be called. + // In AGG there is no need to allocate an array of objects with + // calling their constructors (only single ones). So that, if you + // replace these new/delete to malloc/free make sure that the in-place + // new is called and take care of calling the destructor too. + //------------------------------------------------------------obj_allocator + template<class T> struct obj_allocator + { + static T* allocate() { return new T; } + static void deallocate(T* ptr) { delete ptr; } + }; +} +#endif + + +//-------------------------------------------------------- Default basic types +// +// If the compiler has different capacity of the basic types you can redefine +// them via the compiler command line or by generating agg_config.h that is +// empty by default. +// +#ifndef AGG_INT8 +#define AGG_INT8 signed char +#endif + +#ifndef AGG_INT8U +#define AGG_INT8U unsigned char +#endif + +#ifndef AGG_INT16 +#define AGG_INT16 short +#endif + +#ifndef AGG_INT16U +#define AGG_INT16U unsigned short +#endif + +#ifndef AGG_INT32 +#define AGG_INT32 int +#endif + +#ifndef AGG_INT32U +#define AGG_INT32U unsigned +#endif + +#ifndef AGG_INT64 +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define AGG_INT64 signed __int64 +#else +#define AGG_INT64 signed long long +#endif +#endif + +#ifndef AGG_INT64U +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define AGG_INT64U unsigned __int64 +#else +#define AGG_INT64U unsigned long long +#endif +#endif + +//------------------------------------------------ Some fixes for MS Visual C++ +#if defined(_MSC_VER) +#pragma warning(disable:4786) // Identifier was truncated... +#endif + +#if defined(_MSC_VER) +#define AGG_INLINE __forceinline +#else +#define AGG_INLINE inline +#endif + +namespace agg +{ + //------------------------------------------------------------------------- + typedef AGG_INT8 int8; //----int8 + typedef AGG_INT8U int8u; //----int8u + typedef AGG_INT16 int16; //----int16 + typedef AGG_INT16U int16u; //----int16u + typedef AGG_INT32 int32; //----int32 + typedef AGG_INT32U int32u; //----int32u + typedef AGG_INT64 int64; //----int64 + typedef AGG_INT64U int64u; //----int64u + +#if defined(AGG_FISTP) +#pragma warning(push) +#pragma warning(disable : 4035) //Disable warning "no return value" + AGG_INLINE int iround(double v) //-------iround + { + int t; + __asm fld qword ptr [v] + __asm fistp dword ptr [t] + __asm mov eax, dword ptr [t] + } + AGG_INLINE unsigned uround(double v) //-------uround + { + unsigned t; + __asm fld qword ptr [v] + __asm fistp dword ptr [t] + __asm mov eax, dword ptr [t] + } +#pragma warning(pop) + AGG_INLINE int ifloor(double v) + { + return int(floor(v)); + } + AGG_INLINE unsigned ufloor(double v) //-------ufloor + { + return unsigned(floor(v)); + } + AGG_INLINE int iceil(double v) + { + return int(ceil(v)); + } + AGG_INLINE unsigned uceil(double v) //--------uceil + { + return unsigned(ceil(v)); + } +#elif defined(AGG_QIFIST) + AGG_INLINE int iround(double v) + { + return int(v); + } + AGG_INLINE int uround(double v) + { + return unsigned(v); + } + AGG_INLINE int ifloor(double v) + { + return int(std::floor(v)); + } + AGG_INLINE unsigned ufloor(double v) + { + return unsigned(std::floor(v)); + } + AGG_INLINE int iceil(double v) + { + return int(std::ceil(v)); + } + AGG_INLINE unsigned uceil(double v) + { + return unsigned(std::ceil(v)); + } +#else + AGG_INLINE int iround(double v) + { + return int((v < 0.0) ? v - 0.5 : v + 0.5); + } + AGG_INLINE int uround(double v) + { + return unsigned(v + 0.5); + } + AGG_INLINE int ifloor(double v) + { + int i = int(v); + return i - (i > v); + } + AGG_INLINE unsigned ufloor(double v) + { + return unsigned(v); + } + AGG_INLINE int iceil(double v) + { + return int(std::ceil(v)); + } + AGG_INLINE unsigned uceil(double v) + { + return unsigned(std::ceil(v)); + } +#endif + + //---------------------------------------------------------------saturation + template<int Limit> struct saturation + { + AGG_INLINE static int iround(double v) + { + if(v < double(-Limit)) return -Limit; + if(v > double( Limit)) return Limit; + return agg::iround(v); + } + }; + + //------------------------------------------------------------------mul_one + template<unsigned Shift> struct mul_one + { + AGG_INLINE static unsigned mul(unsigned a, unsigned b) + { + unsigned q = a * b + (1 << (Shift-1)); + return (q + (q >> Shift)) >> Shift; + } + }; + + //------------------------------------------------------------------------- + typedef unsigned char cover_type; //----cover_type + enum cover_scale_e + { + cover_shift = 8, //----cover_shift + cover_size = 1 << cover_shift, //----cover_size + cover_mask = cover_size - 1, //----cover_mask + cover_none = 0, //----cover_none + cover_full = cover_mask //----cover_full + }; + + //----------------------------------------------------poly_subpixel_scale_e + // These constants determine the subpixel accuracy, to be more precise, + // the number of bits of the fractional part of the coordinates. + // The possible coordinate capacity in bits can be calculated by formula: + // sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and + // 8-bits fractional part the capacity is 24 bits. + enum poly_subpixel_scale_e + { + poly_subpixel_shift = 8, //----poly_subpixel_shift + poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale + poly_subpixel_mask = poly_subpixel_scale-1 //----poly_subpixel_mask + }; + + //----------------------------------------------------------filling_rule_e + enum filling_rule_e + { + fill_non_zero, + fill_even_odd + }; + + //-----------------------------------------------------------------------pi + const double pi = 3.14159265358979323846; + + //------------------------------------------------------------------deg2rad + inline double deg2rad(double deg) + { + return deg * pi / 180.0; + } + + //------------------------------------------------------------------rad2deg + inline double rad2deg(double rad) + { + return rad * 180.0 / pi; + } + + //----------------------------------------------------------------rect_base + template<class T> struct rect_base + { + typedef T value_type; + typedef rect_base<T> self_type; + T x1, y1, x2, y2; + + rect_base() {} + rect_base(T x1_, T y1_, T x2_, T y2_) : + x1(x1_), y1(y1_), x2(x2_), y2(y2_) {} + + void init(T x1_, T y1_, T x2_, T y2_) + { + x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_; + } + + const self_type& normalize() + { + T t; + if(x1 > x2) { t = x1; x1 = x2; x2 = t; } + if(y1 > y2) { t = y1; y1 = y2; y2 = t; } + return *this; + } + + bool clip(const self_type& r) + { + if(x2 > r.x2) x2 = r.x2; + if(y2 > r.y2) y2 = r.y2; + if(x1 < r.x1) x1 = r.x1; + if(y1 < r.y1) y1 = r.y1; + return x1 <= x2 && y1 <= y2; + } + + bool is_valid() const + { + return x1 <= x2 && y1 <= y2; + } + + bool hit_test(T x, T y) const + { + return (x >= x1 && x <= x2 && y >= y1 && y <= y2); + } + + bool overlaps(const self_type& r) const + { + return !(r.x1 > x2 || r.x2 < x1 + || r.y1 > y2 || r.y2 < y1); + } + }; + + //-----------------------------------------------------intersect_rectangles + template<class Rect> + inline Rect intersect_rectangles(const Rect& r1, const Rect& r2) + { + Rect r = r1; + + // First process x2,y2 because the other order + // results in Internal Compiler Error under + // Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in + // case of "Maximize Speed" optimization option. + //----------------- + if(r.x2 > r2.x2) r.x2 = r2.x2; + if(r.y2 > r2.y2) r.y2 = r2.y2; + if(r.x1 < r2.x1) r.x1 = r2.x1; + if(r.y1 < r2.y1) r.y1 = r2.y1; + return r; + } + + + //---------------------------------------------------------unite_rectangles + template<class Rect> + inline Rect unite_rectangles(const Rect& r1, const Rect& r2) + { + Rect r = r1; + if(r.x2 < r2.x2) r.x2 = r2.x2; + if(r.y2 < r2.y2) r.y2 = r2.y2; + if(r.x1 > r2.x1) r.x1 = r2.x1; + if(r.y1 > r2.y1) r.y1 = r2.y1; + return r; + } + + typedef rect_base<int> rect_i; //----rect_i + typedef rect_base<float> rect_f; //----rect_f + typedef rect_base<double> rect_d; //----rect_d + + //---------------------------------------------------------path_commands_e + enum path_commands_e + { + path_cmd_stop = 0, //----path_cmd_stop + path_cmd_move_to = 1, //----path_cmd_move_to + path_cmd_line_to = 2, //----path_cmd_line_to + path_cmd_curve3 = 3, //----path_cmd_curve3 + path_cmd_curve4 = 4, //----path_cmd_curve4 + path_cmd_curveN = 5, //----path_cmd_curveN + path_cmd_catrom = 6, //----path_cmd_catrom + path_cmd_ubspline = 7, //----path_cmd_ubspline + path_cmd_end_poly = 0x0F, //----path_cmd_end_poly + path_cmd_mask = 0x0F //----path_cmd_mask + }; + + //------------------------------------------------------------path_flags_e + enum path_flags_e + { + path_flags_none = 0, //----path_flags_none + path_flags_ccw = 0x10, //----path_flags_ccw + path_flags_cw = 0x20, //----path_flags_cw + path_flags_close = 0x40, //----path_flags_close + path_flags_mask = 0xF0 //----path_flags_mask + }; + + //---------------------------------------------------------------is_vertex + inline bool is_vertex(unsigned c) + { + return c >= path_cmd_move_to && c < path_cmd_end_poly; + } + + //--------------------------------------------------------------is_drawing + inline bool is_drawing(unsigned c) + { + return c >= path_cmd_line_to && c < path_cmd_end_poly; + } + + //-----------------------------------------------------------------is_stop + inline bool is_stop(unsigned c) + { + return c == path_cmd_stop; + } + + //--------------------------------------------------------------is_move_to + inline bool is_move_to(unsigned c) + { + return c == path_cmd_move_to; + } + + //--------------------------------------------------------------is_line_to + inline bool is_line_to(unsigned c) + { + return c == path_cmd_line_to; + } + + //----------------------------------------------------------------is_curve + inline bool is_curve(unsigned c) + { + return c == path_cmd_curve3 || c == path_cmd_curve4; + } + + //---------------------------------------------------------------is_curve3 + inline bool is_curve3(unsigned c) + { + return c == path_cmd_curve3; + } + + //---------------------------------------------------------------is_curve4 + inline bool is_curve4(unsigned c) + { + return c == path_cmd_curve4; + } + + //-------------------------------------------------------------is_end_poly + inline bool is_end_poly(unsigned c) + { + return (c & path_cmd_mask) == path_cmd_end_poly; + } + + //----------------------------------------------------------------is_close + inline bool is_close(unsigned c) + { + return (c & ~(path_flags_cw | path_flags_ccw)) == + (path_cmd_end_poly | path_flags_close); + } + + //------------------------------------------------------------is_next_poly + inline bool is_next_poly(unsigned c) + { + return is_stop(c) || is_move_to(c) || is_end_poly(c); + } + + //-------------------------------------------------------------------is_cw + inline bool is_cw(unsigned c) + { + return (c & path_flags_cw) != 0; + } + + //------------------------------------------------------------------is_ccw + inline bool is_ccw(unsigned c) + { + return (c & path_flags_ccw) != 0; + } + + //-------------------------------------------------------------is_oriented + inline bool is_oriented(unsigned c) + { + return (c & (path_flags_cw | path_flags_ccw)) != 0; + } + + //---------------------------------------------------------------is_closed + inline bool is_closed(unsigned c) + { + return (c & path_flags_close) != 0; + } + + //----------------------------------------------------------get_close_flag + inline unsigned get_close_flag(unsigned c) + { + return c & path_flags_close; + } + + //-------------------------------------------------------clear_orientation + inline unsigned clear_orientation(unsigned c) + { + return c & ~(path_flags_cw | path_flags_ccw); + } + + //---------------------------------------------------------get_orientation + inline unsigned get_orientation(unsigned c) + { + return c & (path_flags_cw | path_flags_ccw); + } + + //---------------------------------------------------------set_orientation + inline unsigned set_orientation(unsigned c, unsigned o) + { + return clear_orientation(c) | o; + } + + //--------------------------------------------------------------point_base + template<class T> struct point_base + { + typedef T value_type; + T x,y; + point_base() {} + point_base(T x_, T y_) : x(x_), y(y_) {} + }; + typedef point_base<int> point_i; //-----point_i + typedef point_base<float> point_f; //-----point_f + typedef point_base<double> point_d; //-----point_d + + //-------------------------------------------------------------vertex_base + template<class T> struct vertex_base + { + typedef T value_type; + T x,y; + unsigned cmd; + vertex_base() {} + vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {} + }; + typedef vertex_base<int> vertex_i; //-----vertex_i + typedef vertex_base<float> vertex_f; //-----vertex_f + typedef vertex_base<double> vertex_d; //-----vertex_d + + //----------------------------------------------------------------row_info + template<class T> struct row_info + { + int x1, x2; + T* ptr; + row_info() {} + row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {} + }; + + //----------------------------------------------------------const_row_info + template<class T> struct const_row_info + { + int x1, x2; + const T* ptr; + const_row_info() {} + const_row_info(int x1_, int x2_, const T* ptr_) : + x1(x1_), x2(x2_), ptr(ptr_) {} + }; + + //------------------------------------------------------------is_equal_eps + template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon) + { + bool neg1 = v1 < 0.0; + bool neg2 = v2 < 0.0; + + if (neg1 != neg2) + return std::fabs(v1) < epsilon && std::fabs(v2) < epsilon; + + int int1, int2; + std::frexp(v1, &int1); + std::frexp(v2, &int2); + int min12 = int1 < int2 ? int1 : int2; + + v1 = std::ldexp(v1, -min12); + v2 = std::ldexp(v2, -min12); + + return std::fabs(v1 - v2) < epsilon; + } +} + + +#endif + diff --git a/include/agg_bezier_arc.h b/include/agg_bezier_arc.h new file mode 100644 index 0000000..cfd9308 --- /dev/null +++ b/include/agg_bezier_arc.h @@ -0,0 +1,159 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e., +// 4, 7, 10, or 13 vertices. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_BEZIER_ARC_INCLUDED +#define AGG_BEZIER_ARC_INCLUDED + +#include "agg_conv_transform.h" + +namespace agg +{ + + //----------------------------------------------------------------------- + void arc_to_bezier(double cx, double cy, double rx, double ry, + double start_angle, double sweep_angle, + double* curve); + + + //==============================================================bezier_arc + // + // See implemantaion agg_bezier_arc.cpp + // + class bezier_arc + { + public: + //-------------------------------------------------------------------- + bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {} + bezier_arc(double x, double y, + double rx, double ry, + double start_angle, + double sweep_angle) + { + init(x, y, rx, ry, start_angle, sweep_angle); + } + + //-------------------------------------------------------------------- + void init(double x, double y, + double rx, double ry, + double start_angle, + double sweep_angle); + + //-------------------------------------------------------------------- + void rewind(unsigned) + { + m_vertex = 0; + } + + //-------------------------------------------------------------------- + unsigned vertex(double* x, double* y) + { + if(m_vertex >= m_num_vertices) return path_cmd_stop; + *x = m_vertices[m_vertex]; + *y = m_vertices[m_vertex + 1]; + m_vertex += 2; + return (m_vertex == 2) ? unsigned(path_cmd_move_to) : m_cmd; + } + + // Supplemantary functions. num_vertices() actually returns doubled + // number of vertices. That is, for 1 vertex it returns 2. + //-------------------------------------------------------------------- + unsigned num_vertices() const { return m_num_vertices; } + const double* vertices() const { return m_vertices; } + double* vertices() { return m_vertices; } + + private: + unsigned m_vertex; + unsigned m_num_vertices; + double m_vertices[26]; + unsigned m_cmd; + }; + + + + //==========================================================bezier_arc_svg + // Compute an SVG-style bezier arc. + // + // Computes an elliptical arc from (x1, y1) to (x2, y2). The size and + // orientation of the ellipse are defined by two radii (rx, ry) + // and an x-axis-rotation, which indicates how the ellipse as a whole + // is rotated relative to the current coordinate system. The center + // (cx, cy) of the ellipse is calculated automatically to satisfy the + // constraints imposed by the other parameters. + // large-arc-flag and sweep-flag contribute to the automatic calculations + // and help determine how the arc is drawn. + class bezier_arc_svg + { + public: + //-------------------------------------------------------------------- + bezier_arc_svg() : m_arc(), m_radii_ok(false) {} + + bezier_arc_svg(double x1, double y1, + double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x2, double y2) : + m_arc(), m_radii_ok(false) + { + init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2); + } + + //-------------------------------------------------------------------- + void init(double x1, double y1, + double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x2, double y2); + + //-------------------------------------------------------------------- + bool radii_ok() const { return m_radii_ok; } + + //-------------------------------------------------------------------- + void rewind(unsigned) + { + m_arc.rewind(0); + } + + //-------------------------------------------------------------------- + unsigned vertex(double* x, double* y) + { + return m_arc.vertex(x, y); + } + + // Supplemantary functions. num_vertices() actually returns doubled + // number of vertices. That is, for 1 vertex it returns 2. + //-------------------------------------------------------------------- + unsigned num_vertices() const { return m_arc.num_vertices(); } + const double* vertices() const { return m_arc.vertices(); } + double* vertices() { return m_arc.vertices(); } + + private: + bezier_arc m_arc; + bool m_radii_ok; + }; + + + + +} + + +#endif diff --git a/include/agg_bitset_iterator.h b/include/agg_bitset_iterator.h new file mode 100644 index 0000000..7382d5c --- /dev/null +++ b/include/agg_bitset_iterator.h @@ -0,0 +1,54 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_BITSET_ITERATOR_INCLUDED +#define AGG_BITSET_ITERATOR_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + class bitset_iterator + { + public: + bitset_iterator(const int8u* bits, unsigned offset = 0) : + m_bits(bits + (offset >> 3)), + m_mask(0x80 >> (offset & 7)) + {} + + void operator ++ () + { + m_mask >>= 1; + if(m_mask == 0) + { + ++m_bits; + m_mask = 0x80; + } + } + + unsigned bit() const + { + return (*m_bits) & m_mask; + } + + private: + const int8u* m_bits; + int8u m_mask; + }; + +} + +#endif diff --git a/include/agg_blur.h b/include/agg_blur.h new file mode 100644 index 0000000..fd38e94 --- /dev/null +++ b/include/agg_blur.h @@ -0,0 +1,1505 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// The Stack Blur Algorithm was invented by Mario Klingemann, +// mario@quasimondo.com and described here: +// http://incubator.quasimondo.com/processing/fast_blur_deluxe.php +// (search phrase "Stackblur: Fast But Goodlooking"). +// The major improvement is that there's no more division table +// that was very expensive to create for large blur radii. Insted, +// for 8-bit per channel and radius not exceeding 254 the division is +// replaced by multiplication and shift. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_BLUR_INCLUDED +#define AGG_BLUR_INCLUDED + +#include <cstring> +#include <cmath> +#include "agg_array.h" +#include "agg_pixfmt_base.h" +#include "agg_pixfmt_transposer.h" + +namespace agg +{ + + template<class T> struct stack_blur_tables + { + static int16u const g_stack_blur8_mul[255]; + static int8u const g_stack_blur8_shr[255]; + }; + + //------------------------------------------------------------------------ + template<class T> + int16u const stack_blur_tables<T>::g_stack_blur8_mul[255] = + { + 512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512, + 454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512, + 482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456, + 437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512, + 497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328, + 320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456, + 446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335, + 329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512, + 505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405, + 399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328, + 324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271, + 268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456, + 451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388, + 385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335, + 332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292, + 289,287,285,282,280,278,275,273,271,269,267,265,263,261,259 + }; + + //------------------------------------------------------------------------ + template<class T> + int8u const stack_blur_tables<T>::g_stack_blur8_shr[255] = + { + 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, + 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 + }; + + + + //==============================================================stack_blur + template<class ColorT, class CalculatorT> class stack_blur + { + public: + typedef ColorT color_type; + typedef CalculatorT calculator_type; + + //-------------------------------------------------------------------- + template<class Img> void blur_x(Img& img, unsigned radius) + { + if(radius < 1) return; + + unsigned x, y, xp, i; + unsigned stack_ptr; + unsigned stack_start; + + color_type pix; + color_type* stack_pix; + calculator_type sum; + calculator_type sum_in; + calculator_type sum_out; + + unsigned w = img.width(); + unsigned h = img.height(); + unsigned wm = w - 1; + unsigned div = radius * 2 + 1; + + unsigned div_sum = (radius + 1) * (radius + 1); + unsigned mul_sum = 0; + unsigned shr_sum = 0; + unsigned max_val = color_type::base_mask; + + if(max_val <= 255 && radius < 255) + { + mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[radius]; + shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[radius]; + } + + m_buf.allocate(w, 128); + m_stack.allocate(div, 32); + + for(y = 0; y < h; y++) + { + sum.clear(); + sum_in.clear(); + sum_out.clear(); + + pix = img.pixel(0, y); + for(i = 0; i <= radius; i++) + { + m_stack[i] = pix; + sum.add(pix, i + 1); + sum_out.add(pix); + } + for(i = 1; i <= radius; i++) + { + pix = img.pixel((i > wm) ? wm : i, y); + m_stack[i + radius] = pix; + sum.add(pix, radius + 1 - i); + sum_in.add(pix); + } + + stack_ptr = radius; + for(x = 0; x < w; x++) + { + if(mul_sum) sum.calc_pix(m_buf[x], mul_sum, shr_sum); + else sum.calc_pix(m_buf[x], div_sum); + + sum.sub(sum_out); + + stack_start = stack_ptr + div - radius; + if(stack_start >= div) stack_start -= div; + stack_pix = &m_stack[stack_start]; + + sum_out.sub(*stack_pix); + + xp = x + radius + 1; + if(xp > wm) xp = wm; + pix = img.pixel(xp, y); + + *stack_pix = pix; + + sum_in.add(pix); + sum.add(sum_in); + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix = &m_stack[stack_ptr]; + + sum_out.add(*stack_pix); + sum_in.sub(*stack_pix); + } + img.copy_color_hspan(0, y, w, &m_buf[0]); + } + } + + //-------------------------------------------------------------------- + template<class Img> void blur_y(Img& img, unsigned radius) + { + pixfmt_transposer<Img> img2(img); + blur_x(img2, radius); + } + + //-------------------------------------------------------------------- + template<class Img> void blur(Img& img, unsigned radius) + { + blur_x(img, radius); + pixfmt_transposer<Img> img2(img); + blur_x(img2, radius); + } + + private: + pod_vector<color_type> m_buf; + pod_vector<color_type> m_stack; + }; + + //====================================================stack_blur_calc_rgba + template<class T=unsigned> struct stack_blur_calc_rgba + { + typedef T value_type; + value_type r,g,b,a; + + AGG_INLINE void clear() + { + r = g = b = a = 0; + } + + template<class ArgT> AGG_INLINE void add(const ArgT& v) + { + r += v.r; + g += v.g; + b += v.b; + a += v.a; + } + + template<class ArgT> AGG_INLINE void add(const ArgT& v, unsigned k) + { + r += v.r * k; + g += v.g * k; + b += v.b * k; + a += v.a * k; + } + + template<class ArgT> AGG_INLINE void sub(const ArgT& v) + { + r -= v.r; + g -= v.g; + b -= v.b; + a -= v.a; + } + + template<class ArgT> AGG_INLINE void calc_pix(ArgT& v, unsigned div) + { + typedef typename ArgT::value_type value_type; + v.r = value_type(r / div); + v.g = value_type(g / div); + v.b = value_type(b / div); + v.a = value_type(a / div); + } + + template<class ArgT> + AGG_INLINE void calc_pix(ArgT& v, unsigned mul, unsigned shr) + { + typedef typename ArgT::value_type value_type; + v.r = value_type((r * mul) >> shr); + v.g = value_type((g * mul) >> shr); + v.b = value_type((b * mul) >> shr); + v.a = value_type((a * mul) >> shr); + } + }; + + + //=====================================================stack_blur_calc_rgb + template<class T=unsigned> struct stack_blur_calc_rgb + { + typedef T value_type; + value_type r,g,b; + + AGG_INLINE void clear() + { + r = g = b = 0; + } + + template<class ArgT> AGG_INLINE void add(const ArgT& v) + { + r += v.r; + g += v.g; + b += v.b; + } + + template<class ArgT> AGG_INLINE void add(const ArgT& v, unsigned k) + { + r += v.r * k; + g += v.g * k; + b += v.b * k; + } + + template<class ArgT> AGG_INLINE void sub(const ArgT& v) + { + r -= v.r; + g -= v.g; + b -= v.b; + } + + template<class ArgT> AGG_INLINE void calc_pix(ArgT& v, unsigned div) + { + typedef typename ArgT::value_type value_type; + v.r = value_type(r / div); + v.g = value_type(g / div); + v.b = value_type(b / div); + } + + template<class ArgT> + AGG_INLINE void calc_pix(ArgT& v, unsigned mul, unsigned shr) + { + typedef typename ArgT::value_type value_type; + v.r = value_type((r * mul) >> shr); + v.g = value_type((g * mul) >> shr); + v.b = value_type((b * mul) >> shr); + } + }; + + + //====================================================stack_blur_calc_gray + template<class T=unsigned> struct stack_blur_calc_gray + { + typedef T value_type; + value_type v; + + AGG_INLINE void clear() + { + v = 0; + } + + template<class ArgT> AGG_INLINE void add(const ArgT& a) + { + v += a.v; + } + + template<class ArgT> AGG_INLINE void add(const ArgT& a, unsigned k) + { + v += a.v * k; + } + + template<class ArgT> AGG_INLINE void sub(const ArgT& a) + { + v -= a.v; + } + + template<class ArgT> AGG_INLINE void calc_pix(ArgT& a, unsigned div) + { + typedef typename ArgT::value_type value_type; + a.v = value_type(v / div); + } + + template<class ArgT> + AGG_INLINE void calc_pix(ArgT& a, unsigned mul, unsigned shr) + { + typedef typename ArgT::value_type value_type; + a.v = value_type((v * mul) >> shr); + } + }; + + + + //========================================================stack_blur_gray8 + template<class Img> + void stack_blur_gray8(Img& img, unsigned rx, unsigned ry) + { + unsigned x, y, xp, yp, i; + unsigned stack_ptr; + unsigned stack_start; + + const int8u* src_pix_ptr; + int8u* dst_pix_ptr; + unsigned pix; + unsigned stack_pix; + unsigned sum; + unsigned sum_in; + unsigned sum_out; + + unsigned w = img.width(); + unsigned h = img.height(); + unsigned wm = w - 1; + unsigned hm = h - 1; + + unsigned div; + unsigned mul_sum; + unsigned shr_sum; + + pod_vector<int8u> stack; + + if(rx > 0) + { + if(rx > 254) rx = 254; + div = rx * 2 + 1; + mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[rx]; + shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[rx]; + stack.allocate(div); + + for(y = 0; y < h; y++) + { + sum = sum_in = sum_out = 0; + + src_pix_ptr = img.pix_ptr(0, y); + pix = *src_pix_ptr; + for(i = 0; i <= rx; i++) + { + stack[i] = pix; + sum += pix * (i + 1); + sum_out += pix; + } + for(i = 1; i <= rx; i++) + { + if(i <= wm) src_pix_ptr += Img::pix_width; + pix = *src_pix_ptr; + stack[i + rx] = pix; + sum += pix * (rx + 1 - i); + sum_in += pix; + } + + stack_ptr = rx; + xp = rx; + if(xp > wm) xp = wm; + src_pix_ptr = img.pix_ptr(xp, y); + dst_pix_ptr = img.pix_ptr(0, y); + for(x = 0; x < w; x++) + { + *dst_pix_ptr = (sum * mul_sum) >> shr_sum; + dst_pix_ptr += Img::pix_width; + + sum -= sum_out; + + stack_start = stack_ptr + div - rx; + if(stack_start >= div) stack_start -= div; + sum_out -= stack[stack_start]; + + if(xp < wm) + { + src_pix_ptr += Img::pix_width; + pix = *src_pix_ptr; + ++xp; + } + + stack[stack_start] = pix; + + sum_in += pix; + sum += sum_in; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix = stack[stack_ptr]; + + sum_out += stack_pix; + sum_in -= stack_pix; + } + } + } + + if(ry > 0) + { + if(ry > 254) ry = 254; + div = ry * 2 + 1; + mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[ry]; + shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[ry]; + stack.allocate(div); + + int stride = img.stride(); + for(x = 0; x < w; x++) + { + sum = sum_in = sum_out = 0; + + src_pix_ptr = img.pix_ptr(x, 0); + pix = *src_pix_ptr; + for(i = 0; i <= ry; i++) + { + stack[i] = pix; + sum += pix * (i + 1); + sum_out += pix; + } + for(i = 1; i <= ry; i++) + { + if(i <= hm) src_pix_ptr += stride; + pix = *src_pix_ptr; + stack[i + ry] = pix; + sum += pix * (ry + 1 - i); + sum_in += pix; + } + + stack_ptr = ry; + yp = ry; + if(yp > hm) yp = hm; + src_pix_ptr = img.pix_ptr(x, yp); + dst_pix_ptr = img.pix_ptr(x, 0); + for(y = 0; y < h; y++) + { + *dst_pix_ptr = (sum * mul_sum) >> shr_sum; + dst_pix_ptr += stride; + + sum -= sum_out; + + stack_start = stack_ptr + div - ry; + if(stack_start >= div) stack_start -= div; + sum_out -= stack[stack_start]; + + if(yp < hm) + { + src_pix_ptr += stride; + pix = *src_pix_ptr; + ++yp; + } + + stack[stack_start] = pix; + + sum_in += pix; + sum += sum_in; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix = stack[stack_ptr]; + + sum_out += stack_pix; + sum_in -= stack_pix; + } + } + } + } + + + + //========================================================stack_blur_rgb24 + template<class Img> + void stack_blur_rgb24(Img& img, unsigned rx, unsigned ry) + { + typedef typename Img::color_type color_type; + typedef typename Img::order_type order_type; + enum order_e + { + R = order_type::R, + G = order_type::G, + B = order_type::B + }; + + unsigned x, y, xp, yp, i; + unsigned stack_ptr; + unsigned stack_start; + + const int8u* src_pix_ptr; + int8u* dst_pix_ptr; + color_type* stack_pix_ptr; + + unsigned sum_r; + unsigned sum_g; + unsigned sum_b; + unsigned sum_in_r; + unsigned sum_in_g; + unsigned sum_in_b; + unsigned sum_out_r; + unsigned sum_out_g; + unsigned sum_out_b; + + unsigned w = img.width(); + unsigned h = img.height(); + unsigned wm = w - 1; + unsigned hm = h - 1; + + unsigned div; + unsigned mul_sum; + unsigned shr_sum; + + pod_vector<color_type> stack; + + if(rx > 0) + { + if(rx > 254) rx = 254; + div = rx * 2 + 1; + mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[rx]; + shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[rx]; + stack.allocate(div); + + for(y = 0; y < h; y++) + { + sum_r = + sum_g = + sum_b = + sum_in_r = + sum_in_g = + sum_in_b = + sum_out_r = + sum_out_g = + sum_out_b = 0; + + src_pix_ptr = img.pix_ptr(0, y); + for(i = 0; i <= rx; i++) + { + stack_pix_ptr = &stack[i]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + sum_r += src_pix_ptr[R] * (i + 1); + sum_g += src_pix_ptr[G] * (i + 1); + sum_b += src_pix_ptr[B] * (i + 1); + sum_out_r += src_pix_ptr[R]; + sum_out_g += src_pix_ptr[G]; + sum_out_b += src_pix_ptr[B]; + } + for(i = 1; i <= rx; i++) + { + if(i <= wm) src_pix_ptr += Img::pix_width; + stack_pix_ptr = &stack[i + rx]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + sum_r += src_pix_ptr[R] * (rx + 1 - i); + sum_g += src_pix_ptr[G] * (rx + 1 - i); + sum_b += src_pix_ptr[B] * (rx + 1 - i); + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + } + + stack_ptr = rx; + xp = rx; + if(xp > wm) xp = wm; + src_pix_ptr = img.pix_ptr(xp, y); + dst_pix_ptr = img.pix_ptr(0, y); + for(x = 0; x < w; x++) + { + dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; + dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; + dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; + dst_pix_ptr += Img::pix_width; + + sum_r -= sum_out_r; + sum_g -= sum_out_g; + sum_b -= sum_out_b; + + stack_start = stack_ptr + div - rx; + if(stack_start >= div) stack_start -= div; + stack_pix_ptr = &stack[stack_start]; + + sum_out_r -= stack_pix_ptr->r; + sum_out_g -= stack_pix_ptr->g; + sum_out_b -= stack_pix_ptr->b; + + if(xp < wm) + { + src_pix_ptr += Img::pix_width; + ++xp; + } + + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_r += sum_in_r; + sum_g += sum_in_g; + sum_b += sum_in_b; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix_ptr = &stack[stack_ptr]; + + sum_out_r += stack_pix_ptr->r; + sum_out_g += stack_pix_ptr->g; + sum_out_b += stack_pix_ptr->b; + sum_in_r -= stack_pix_ptr->r; + sum_in_g -= stack_pix_ptr->g; + sum_in_b -= stack_pix_ptr->b; + } + } + } + + if(ry > 0) + { + if(ry > 254) ry = 254; + div = ry * 2 + 1; + mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[ry]; + shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[ry]; + stack.allocate(div); + + int stride = img.stride(); + for(x = 0; x < w; x++) + { + sum_r = + sum_g = + sum_b = + sum_in_r = + sum_in_g = + sum_in_b = + sum_out_r = + sum_out_g = + sum_out_b = 0; + + src_pix_ptr = img.pix_ptr(x, 0); + for(i = 0; i <= ry; i++) + { + stack_pix_ptr = &stack[i]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + sum_r += src_pix_ptr[R] * (i + 1); + sum_g += src_pix_ptr[G] * (i + 1); + sum_b += src_pix_ptr[B] * (i + 1); + sum_out_r += src_pix_ptr[R]; + sum_out_g += src_pix_ptr[G]; + sum_out_b += src_pix_ptr[B]; + } + for(i = 1; i <= ry; i++) + { + if(i <= hm) src_pix_ptr += stride; + stack_pix_ptr = &stack[i + ry]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + sum_r += src_pix_ptr[R] * (ry + 1 - i); + sum_g += src_pix_ptr[G] * (ry + 1 - i); + sum_b += src_pix_ptr[B] * (ry + 1 - i); + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + } + + stack_ptr = ry; + yp = ry; + if(yp > hm) yp = hm; + src_pix_ptr = img.pix_ptr(x, yp); + dst_pix_ptr = img.pix_ptr(x, 0); + for(y = 0; y < h; y++) + { + dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; + dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; + dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; + dst_pix_ptr += stride; + + sum_r -= sum_out_r; + sum_g -= sum_out_g; + sum_b -= sum_out_b; + + stack_start = stack_ptr + div - ry; + if(stack_start >= div) stack_start -= div; + + stack_pix_ptr = &stack[stack_start]; + sum_out_r -= stack_pix_ptr->r; + sum_out_g -= stack_pix_ptr->g; + sum_out_b -= stack_pix_ptr->b; + + if(yp < hm) + { + src_pix_ptr += stride; + ++yp; + } + + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_r += sum_in_r; + sum_g += sum_in_g; + sum_b += sum_in_b; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix_ptr = &stack[stack_ptr]; + + sum_out_r += stack_pix_ptr->r; + sum_out_g += stack_pix_ptr->g; + sum_out_b += stack_pix_ptr->b; + sum_in_r -= stack_pix_ptr->r; + sum_in_g -= stack_pix_ptr->g; + sum_in_b -= stack_pix_ptr->b; + } + } + } + } + + + + //=======================================================stack_blur_rgba32 + template<class Img> + void stack_blur_rgba32(Img& img, unsigned rx, unsigned ry) + { + typedef typename Img::color_type color_type; + typedef typename Img::order_type order_type; + enum order_e + { + R = order_type::R, + G = order_type::G, + B = order_type::B, + A = order_type::A + }; + + unsigned x, y, xp, yp, i; + unsigned stack_ptr; + unsigned stack_start; + + const int8u* src_pix_ptr; + int8u* dst_pix_ptr; + color_type* stack_pix_ptr; + + unsigned sum_r; + unsigned sum_g; + unsigned sum_b; + unsigned sum_a; + unsigned sum_in_r; + unsigned sum_in_g; + unsigned sum_in_b; + unsigned sum_in_a; + unsigned sum_out_r; + unsigned sum_out_g; + unsigned sum_out_b; + unsigned sum_out_a; + + unsigned w = img.width(); + unsigned h = img.height(); + unsigned wm = w - 1; + unsigned hm = h - 1; + + unsigned div; + unsigned mul_sum; + unsigned shr_sum; + + pod_vector<color_type> stack; + + if(rx > 0) + { + if(rx > 254) rx = 254; + div = rx * 2 + 1; + mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[rx]; + shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[rx]; + stack.allocate(div); + + for(y = 0; y < h; y++) + { + sum_r = + sum_g = + sum_b = + sum_a = + sum_in_r = + sum_in_g = + sum_in_b = + sum_in_a = + sum_out_r = + sum_out_g = + sum_out_b = + sum_out_a = 0; + + src_pix_ptr = img.pix_ptr(0, y); + for(i = 0; i <= rx; i++) + { + stack_pix_ptr = &stack[i]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + sum_r += src_pix_ptr[R] * (i + 1); + sum_g += src_pix_ptr[G] * (i + 1); + sum_b += src_pix_ptr[B] * (i + 1); + sum_a += src_pix_ptr[A] * (i + 1); + sum_out_r += src_pix_ptr[R]; + sum_out_g += src_pix_ptr[G]; + sum_out_b += src_pix_ptr[B]; + sum_out_a += src_pix_ptr[A]; + } + for(i = 1; i <= rx; i++) + { + if(i <= wm) src_pix_ptr += Img::pix_width; + stack_pix_ptr = &stack[i + rx]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + sum_r += src_pix_ptr[R] * (rx + 1 - i); + sum_g += src_pix_ptr[G] * (rx + 1 - i); + sum_b += src_pix_ptr[B] * (rx + 1 - i); + sum_a += src_pix_ptr[A] * (rx + 1 - i); + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_in_a += src_pix_ptr[A]; + } + + stack_ptr = rx; + xp = rx; + if(xp > wm) xp = wm; + src_pix_ptr = img.pix_ptr(xp, y); + dst_pix_ptr = img.pix_ptr(0, y); + for(x = 0; x < w; x++) + { + dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; + dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; + dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; + dst_pix_ptr[A] = (sum_a * mul_sum) >> shr_sum; + dst_pix_ptr += Img::pix_width; + + sum_r -= sum_out_r; + sum_g -= sum_out_g; + sum_b -= sum_out_b; + sum_a -= sum_out_a; + + stack_start = stack_ptr + div - rx; + if(stack_start >= div) stack_start -= div; + stack_pix_ptr = &stack[stack_start]; + + sum_out_r -= stack_pix_ptr->r; + sum_out_g -= stack_pix_ptr->g; + sum_out_b -= stack_pix_ptr->b; + sum_out_a -= stack_pix_ptr->a; + + if(xp < wm) + { + src_pix_ptr += Img::pix_width; + ++xp; + } + + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_in_a += src_pix_ptr[A]; + sum_r += sum_in_r; + sum_g += sum_in_g; + sum_b += sum_in_b; + sum_a += sum_in_a; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix_ptr = &stack[stack_ptr]; + + sum_out_r += stack_pix_ptr->r; + sum_out_g += stack_pix_ptr->g; + sum_out_b += stack_pix_ptr->b; + sum_out_a += stack_pix_ptr->a; + sum_in_r -= stack_pix_ptr->r; + sum_in_g -= stack_pix_ptr->g; + sum_in_b -= stack_pix_ptr->b; + sum_in_a -= stack_pix_ptr->a; + } + } + } + + if(ry > 0) + { + if(ry > 254) ry = 254; + div = ry * 2 + 1; + mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[ry]; + shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[ry]; + stack.allocate(div); + + int stride = img.stride(); + for(x = 0; x < w; x++) + { + sum_r = + sum_g = + sum_b = + sum_a = + sum_in_r = + sum_in_g = + sum_in_b = + sum_in_a = + sum_out_r = + sum_out_g = + sum_out_b = + sum_out_a = 0; + + src_pix_ptr = img.pix_ptr(x, 0); + for(i = 0; i <= ry; i++) + { + stack_pix_ptr = &stack[i]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + sum_r += src_pix_ptr[R] * (i + 1); + sum_g += src_pix_ptr[G] * (i + 1); + sum_b += src_pix_ptr[B] * (i + 1); + sum_a += src_pix_ptr[A] * (i + 1); + sum_out_r += src_pix_ptr[R]; + sum_out_g += src_pix_ptr[G]; + sum_out_b += src_pix_ptr[B]; + sum_out_a += src_pix_ptr[A]; + } + for(i = 1; i <= ry; i++) + { + if(i <= hm) src_pix_ptr += stride; + stack_pix_ptr = &stack[i + ry]; + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + sum_r += src_pix_ptr[R] * (ry + 1 - i); + sum_g += src_pix_ptr[G] * (ry + 1 - i); + sum_b += src_pix_ptr[B] * (ry + 1 - i); + sum_a += src_pix_ptr[A] * (ry + 1 - i); + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_in_a += src_pix_ptr[A]; + } + + stack_ptr = ry; + yp = ry; + if(yp > hm) yp = hm; + src_pix_ptr = img.pix_ptr(x, yp); + dst_pix_ptr = img.pix_ptr(x, 0); + for(y = 0; y < h; y++) + { + dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum; + dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum; + dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum; + dst_pix_ptr[A] = (sum_a * mul_sum) >> shr_sum; + dst_pix_ptr += stride; + + sum_r -= sum_out_r; + sum_g -= sum_out_g; + sum_b -= sum_out_b; + sum_a -= sum_out_a; + + stack_start = stack_ptr + div - ry; + if(stack_start >= div) stack_start -= div; + + stack_pix_ptr = &stack[stack_start]; + sum_out_r -= stack_pix_ptr->r; + sum_out_g -= stack_pix_ptr->g; + sum_out_b -= stack_pix_ptr->b; + sum_out_a -= stack_pix_ptr->a; + + if(yp < hm) + { + src_pix_ptr += stride; + ++yp; + } + + stack_pix_ptr->r = src_pix_ptr[R]; + stack_pix_ptr->g = src_pix_ptr[G]; + stack_pix_ptr->b = src_pix_ptr[B]; + stack_pix_ptr->a = src_pix_ptr[A]; + + sum_in_r += src_pix_ptr[R]; + sum_in_g += src_pix_ptr[G]; + sum_in_b += src_pix_ptr[B]; + sum_in_a += src_pix_ptr[A]; + sum_r += sum_in_r; + sum_g += sum_in_g; + sum_b += sum_in_b; + sum_a += sum_in_a; + + ++stack_ptr; + if(stack_ptr >= div) stack_ptr = 0; + stack_pix_ptr = &stack[stack_ptr]; + + sum_out_r += stack_pix_ptr->r; + sum_out_g += stack_pix_ptr->g; + sum_out_b += stack_pix_ptr->b; + sum_out_a += stack_pix_ptr->a; + sum_in_r -= stack_pix_ptr->r; + sum_in_g -= stack_pix_ptr->g; + sum_in_b -= stack_pix_ptr->b; + sum_in_a -= stack_pix_ptr->a; + } + } + } + } + + + + //===========================================================recursive_blur + template<class ColorT, class CalculatorT> class recursive_blur + { + public: + typedef ColorT color_type; + typedef CalculatorT calculator_type; + typedef typename color_type::value_type value_type; + typedef typename calculator_type::value_type calc_type; + + //-------------------------------------------------------------------- + template<class Img> void blur_x(Img& img, double radius) + { + if(radius < 0.62) return; + if(img.width() < 3) return; + + calc_type s = calc_type(radius * 0.5); + calc_type q = calc_type((s < 2.5) ? + 3.97156 - 4.14554 * std::sqrt(1 - 0.26891 * s) : + 0.98711 * s - 0.96330); + + calc_type q2 = calc_type(q * q); + calc_type q3 = calc_type(q2 * q); + + calc_type b0 = calc_type(1.0 / (1.578250 + + 2.444130 * q + + 1.428100 * q2 + + 0.422205 * q3)); + + calc_type b1 = calc_type( 2.44413 * q + + 2.85619 * q2 + + 1.26661 * q3); + + calc_type b2 = calc_type(-1.42810 * q2 + + -1.26661 * q3); + + calc_type b3 = calc_type(0.422205 * q3); + + calc_type b = calc_type(1 - (b1 + b2 + b3) * b0); + + b1 *= b0; + b2 *= b0; + b3 *= b0; + + int w = img.width(); + int h = img.height(); + int wm = w-1; + int x, y; + + m_sum1.allocate(w); + m_sum2.allocate(w); + m_buf.allocate(w); + + for(y = 0; y < h; y++) + { + calculator_type c; + c.from_pix(img.pixel(0, y)); + m_sum1[0].calc(b, b1, b2, b3, c, c, c, c); + c.from_pix(img.pixel(1, y)); + m_sum1[1].calc(b, b1, b2, b3, c, m_sum1[0], m_sum1[0], m_sum1[0]); + c.from_pix(img.pixel(2, y)); + m_sum1[2].calc(b, b1, b2, b3, c, m_sum1[1], m_sum1[0], m_sum1[0]); + + for(x = 3; x < w; ++x) + { + c.from_pix(img.pixel(x, y)); + m_sum1[x].calc(b, b1, b2, b3, c, m_sum1[x-1], m_sum1[x-2], m_sum1[x-3]); + } + + m_sum2[wm ].calc(b, b1, b2, b3, m_sum1[wm ], m_sum1[wm ], m_sum1[wm], m_sum1[wm]); + m_sum2[wm-1].calc(b, b1, b2, b3, m_sum1[wm-1], m_sum2[wm ], m_sum2[wm], m_sum2[wm]); + m_sum2[wm-2].calc(b, b1, b2, b3, m_sum1[wm-2], m_sum2[wm-1], m_sum2[wm], m_sum2[wm]); + m_sum2[wm ].to_pix(m_buf[wm ]); + m_sum2[wm-1].to_pix(m_buf[wm-1]); + m_sum2[wm-2].to_pix(m_buf[wm-2]); + + for(x = wm-3; x >= 0; --x) + { + m_sum2[x].calc(b, b1, b2, b3, m_sum1[x], m_sum2[x+1], m_sum2[x+2], m_sum2[x+3]); + m_sum2[x].to_pix(m_buf[x]); + } + img.copy_color_hspan(0, y, w, &m_buf[0]); + } + } + + //-------------------------------------------------------------------- + template<class Img> void blur_y(Img& img, double radius) + { + pixfmt_transposer<Img> img2(img); + blur_x(img2, radius); + } + + //-------------------------------------------------------------------- + template<class Img> void blur(Img& img, double radius) + { + blur_x(img, radius); + pixfmt_transposer<Img> img2(img); + blur_x(img2, radius); + } + + private: + agg::pod_vector<calculator_type> m_sum1; + agg::pod_vector<calculator_type> m_sum2; + agg::pod_vector<color_type> m_buf; + }; + + + //=================================================recursive_blur_calc_rgba + template<class T=double> struct recursive_blur_calc_rgba + { + typedef T value_type; + typedef recursive_blur_calc_rgba<T> self_type; + + value_type r,g,b,a; + + template<class ColorT> + AGG_INLINE void from_pix(const ColorT& c) + { + r = c.r; + g = c.g; + b = c.b; + a = c.a; + } + + AGG_INLINE void calc(value_type b1, + value_type b2, + value_type b3, + value_type b4, + const self_type& c1, + const self_type& c2, + const self_type& c3, + const self_type& c4) + { + r = b1*c1.r + b2*c2.r + b3*c3.r + b4*c4.r; + g = b1*c1.g + b2*c2.g + b3*c3.g + b4*c4.g; + b = b1*c1.b + b2*c2.b + b3*c3.b + b4*c4.b; + a = b1*c1.a + b2*c2.a + b3*c3.a + b4*c4.a; + } + + template<class ColorT> + AGG_INLINE void to_pix(ColorT& c) const + { + typedef typename ColorT::value_type cv_type; + c.r = cv_type(r); + c.g = cv_type(g); + c.b = cv_type(b); + c.a = cv_type(a); + } + }; + + + //=================================================recursive_blur_calc_rgb + template<class T=double> struct recursive_blur_calc_rgb + { + typedef T value_type; + typedef recursive_blur_calc_rgb<T> self_type; + + value_type r,g,b; + + template<class ColorT> + AGG_INLINE void from_pix(const ColorT& c) + { + r = c.r; + g = c.g; + b = c.b; + } + + AGG_INLINE void calc(value_type b1, + value_type b2, + value_type b3, + value_type b4, + const self_type& c1, + const self_type& c2, + const self_type& c3, + const self_type& c4) + { + r = b1*c1.r + b2*c2.r + b3*c3.r + b4*c4.r; + g = b1*c1.g + b2*c2.g + b3*c3.g + b4*c4.g; + b = b1*c1.b + b2*c2.b + b3*c3.b + b4*c4.b; + } + + template<class ColorT> + AGG_INLINE void to_pix(ColorT& c) const + { + typedef typename ColorT::value_type cv_type; + c.r = cv_type(r); + c.g = cv_type(g); + c.b = cv_type(b); + } + }; + + + //================================================recursive_blur_calc_gray + template<class T=double> struct recursive_blur_calc_gray + { + typedef T value_type; + typedef recursive_blur_calc_gray<T> self_type; + + value_type v; + + template<class ColorT> + AGG_INLINE void from_pix(const ColorT& c) + { + v = c.v; + } + + AGG_INLINE void calc(value_type b1, + value_type b2, + value_type b3, + value_type b4, + const self_type& c1, + const self_type& c2, + const self_type& c3, + const self_type& c4) + { + v = b1*c1.v + b2*c2.v + b3*c3.v + b4*c4.v; + } + + template<class ColorT> + AGG_INLINE void to_pix(ColorT& c) const + { + typedef typename ColorT::value_type cv_type; + c.v = cv_type(v); + } + }; + + //================================================slight_blur + // Special-purpose filter for applying a Gaussian blur with a radius small enough + // that the blur only affects adjacent pixels. A Gaussian curve with a standard + // deviation of r/2 is used, as per the HTML/CSS spec. At 3 standard deviations, + // the contribution drops to less than 0.005, i.e. less than half a percent, + // therefore the radius can be at least 1.33 before errors become significant. + // This filter is useful for smoothing artifacts caused by detail rendered + // at the pixel scale, e.g. single-pixel lines. Note that the filter should + // only be used with premultiplied pixel formats (or those without alpha). + // See the "line_thickness" example for a demonstration. + template<class PixFmt> + class slight_blur + { + public: + typedef typename PixFmt::pixel_type pixel_type; + typedef typename PixFmt::value_type value_type; + typedef typename PixFmt::order_type order_type; + + slight_blur(double r = 1.33) + { + radius(r); + } + + void radius(double r) + { + if (r > 0) + { + // Sample the gaussian curve at 0 and r/2 standard deviations. + // At 3 standard deviations, the response is < 0.005. + double pi = 3.14159; + double n = 2 / r; + m_g0 = 1 / std::sqrt(2 * pi); + m_g1 = m_g0 * exp(-n * n); + + // Normalize. + double sum = m_g0 + 2 * m_g1; + m_g0 /= sum; + m_g1 /= sum; + } + else + { + m_g0 = 1; + m_g1 = 0; + } + } + + void blur(PixFmt& img, rect_i bounds) + { + // Make sure we stay within the image area. + bounds.clip(rect_i(0, 0, img.width() - 1, img.height() - 1)); + + int w = bounds.x2 - bounds.x1 + 1; + int h = bounds.y2 - bounds.y1 + 1; + + if (w < 3 || h < 3) return; + + // Allocate 3 rows of buffer space. + m_buf.allocate(w * 3); + + // Set up row pointers + pixel_type * begin = &m_buf[0]; + pixel_type * r0 = begin; + pixel_type * r1 = r0 + w; + pixel_type * r2 = r1 + w; + pixel_type * end = r2 + w; + + // Horizontally blur the first two input rows. + calc_row(img, bounds.x1, bounds.y1, w, r0); + std::memcpy(r1, r0, w * sizeof(pixel_type)); + + for (int y = 0; ; ) + { + // Get pointer to first pixel. + pixel_type* p = img.pix_value_ptr(bounds.x1, bounds.y1 + y, bounds.x1 + w); + + // Horizontally blur the row below. + if (y + 1 < h) + { + calc_row(img, bounds.x1, bounds.y1 + y + 1, w, r2); + } + else + { + std::memcpy(r2, r1, w * sizeof(pixel_type)); // duplicate bottom row + } + + // Combine blurred rows into destination. + for (int x = 0; x < w; ++x) + { + calc_pixel(*r0++, *r1++, *r2++, *p++); + } + + if (++y >= h) break; + + // Wrap bottom row pointer around to top of buffer. + if (r2 == end) r2 = begin; + else if (r1 == end) r1 = begin; + else if (r0 == end) r0 = begin; + } + } + + private: + void calc_row(PixFmt& img, int x, int y, int w, pixel_type* row) + { + const int wm = w - 1; + + pixel_type* p = img.pix_value_ptr(x, y, w); + + pixel_type c[3]; + pixel_type* p0 = c; + pixel_type* p1 = c + 1; + pixel_type* p2 = c + 2; + pixel_type* end = c + 3; + *p0 = *p1 = *p; + + for (int x = 0; x < wm; ++x) + { + *p2 = *(p = p->next()); + + calc_pixel(*p0++, *p1++, *p2++, *row++); + + if (p0 == end) p0 = c; + else if (p1 == end) p1 = c; + else if (p2 == end) p2 = c; + } + + calc_pixel(*p0, *p1, *p1, *row); + } + + void calc_pixel( + pixel_type const & c1, + pixel_type const & c2, + pixel_type const & c3, + pixel_type & x) + { + calc_pixel(c1, c2, c3, x, PixFmt::pixfmt_category()); + } + + void calc_pixel( + pixel_type const & c1, + pixel_type const & c2, + pixel_type const & c3, + pixel_type & x, + pixfmt_gray_tag) + { + x.c[0] = calc_value(c1.c[0], c2.c[0], c3.c[0]); + } + + void calc_pixel( + pixel_type const & c1, + pixel_type const & c2, + pixel_type const & c3, + pixel_type & x, + pixfmt_rgb_tag) + { + enum { R = order_type::R, G = order_type::G, B = order_type::B }; + x.c[R] = calc_value(c1.c[R], c2.c[R], c3.c[R]); + x.c[G] = calc_value(c1.c[G], c2.c[G], c3.c[G]); + x.c[B] = calc_value(c1.c[B], c2.c[B], c3.c[B]); + } + + void calc_pixel( + pixel_type const & c1, + pixel_type const & c2, + pixel_type const & c3, + pixel_type & x, + pixfmt_rgba_tag) + { + enum { R = order_type::R, G = order_type::G, B = order_type::B, A = order_type::A }; + x.c[R] = calc_value(c1.c[R], c2.c[R], c3.c[R]); + x.c[G] = calc_value(c1.c[G], c2.c[G], c3.c[G]); + x.c[B] = calc_value(c1.c[B], c2.c[B], c3.c[B]); + x.c[A] = calc_value(c1.c[A], c2.c[A], c3.c[A]); + } + + value_type calc_value(value_type v1, value_type v2, value_type v3) + { + return value_type(m_g1 * v1 + m_g0 * v2 + m_g1 * v3); + } + + double m_g0, m_g1; + pod_vector<pixel_type> m_buf; + }; + + // Helper functions for applying blur to a surface without having to create an intermediate object. + + template<class PixFmt> + void apply_slight_blur(PixFmt& img, const rect_i& bounds, double r = 1) + { + if (r > 0) slight_blur<PixFmt>(r).blur(img, bounds); + } + + template<class PixFmt> + void apply_slight_blur(PixFmt& img, double r = 1) + { + if (r > 0) slight_blur<PixFmt>(r).blur(img, rect_i(0, 0, img.width() - 1, img.height() - 1)); + } + + template<class PixFmt> + void apply_slight_blur(renderer_base<PixFmt>& img, const rect_i& bounds, double r = 1) + { + if (r > 0) slight_blur<PixFmt>(r).blur(img.ren(), bounds); + } + + template<class PixFmt> + void apply_slight_blur(renderer_base<PixFmt>& img, double r = 1) + { + if (r > 0) slight_blur<PixFmt>(r).blur(img.ren(), img.clip_box()); + } +} + + + + +#endif diff --git a/include/agg_bounding_rect.h b/include/agg_bounding_rect.h new file mode 100644 index 0000000..f13b863 --- /dev/null +++ b/include/agg_bounding_rect.h @@ -0,0 +1,116 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// bounding_rect function template +// +//---------------------------------------------------------------------------- +#ifndef AGG_BOUNDING_RECT_INCLUDED +#define AGG_BOUNDING_RECT_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //-----------------------------------------------------------bounding_rect + template<class VertexSource, class GetId, class CoordT> + bool bounding_rect(VertexSource& vs, GetId& gi, + unsigned start, unsigned num, + CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2) + { + unsigned i; + double x; + double y; + bool first = true; + + *x1 = CoordT(1); + *y1 = CoordT(1); + *x2 = CoordT(0); + *y2 = CoordT(0); + + for(i = 0; i < num; i++) + { + vs.rewind(gi[start + i]); + unsigned cmd; + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + if(is_vertex(cmd)) + { + if(first) + { + *x1 = CoordT(x); + *y1 = CoordT(y); + *x2 = CoordT(x); + *y2 = CoordT(y); + first = false; + } + else + { + if(CoordT(x) < *x1) *x1 = CoordT(x); + if(CoordT(y) < *y1) *y1 = CoordT(y); + if(CoordT(x) > *x2) *x2 = CoordT(x); + if(CoordT(y) > *y2) *y2 = CoordT(y); + } + } + } + } + return *x1 <= *x2 && *y1 <= *y2; + } + + + //-----------------------------------------------------bounding_rect_single + template<class VertexSource, class CoordT> + bool bounding_rect_single(VertexSource& vs, unsigned path_id, + CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2) + { + double x; + double y; + bool first = true; + + *x1 = CoordT(1); + *y1 = CoordT(1); + *x2 = CoordT(0); + *y2 = CoordT(0); + + vs.rewind(path_id); + unsigned cmd; + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + if(is_vertex(cmd)) + { + if(first) + { + *x1 = CoordT(x); + *y1 = CoordT(y); + *x2 = CoordT(x); + *y2 = CoordT(y); + first = false; + } + else + { + if(CoordT(x) < *x1) *x1 = CoordT(x); + if(CoordT(y) < *y1) *y1 = CoordT(y); + if(CoordT(x) > *x2) *x2 = CoordT(x); + if(CoordT(y) > *y2) *y2 = CoordT(y); + } + } + } + return *x1 <= *x2 && *y1 <= *y2; + } + + +} + +#endif diff --git a/include/agg_bspline.h b/include/agg_bspline.h new file mode 100644 index 0000000..2c1ed9a --- /dev/null +++ b/include/agg_bspline.h @@ -0,0 +1,76 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class bspline +// +//---------------------------------------------------------------------------- + +#ifndef AGG_BSPLINE_INCLUDED +#define AGG_BSPLINE_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + //----------------------------------------------------------------bspline + // A very simple class of Bi-cubic Spline interpolation. + // First call init(num, x[], y[]) where num - number of source points, + // x, y - arrays of X and Y values respectively. Here Y must be a function + // of X. It means that all the X-coordinates must be arranged in the ascending + // order. + // Then call get(x) that calculates a value Y for the respective X. + // The class supports extrapolation, i.e. you can call get(x) where x is + // outside the given with init() X-range. Extrapolation is a simple linear + // function. + // + // See Implementation agg_bspline.cpp + //------------------------------------------------------------------------ + class bspline + { + public: + bspline(); + bspline(int num); + bspline(int num, const double* x, const double* y); + + void init(int num); + void add_point(double x, double y); + void prepare(); + + void init(int num, const double* x, const double* y); + + double get(double x) const; + double get_stateful(double x) const; + + private: + bspline(const bspline&); + const bspline& operator = (const bspline&); + + static void bsearch(int n, const double *x, double x0, int *i); + double extrapolation_left(double x) const; + double extrapolation_right(double x) const; + double interpolation(double x, int i) const; + + int m_max; + int m_num; + double* m_x; + double* m_y; + pod_array<double> m_am; + mutable int m_last_idx; + }; + + +} + +#endif diff --git a/include/agg_clip_liang_barsky.h b/include/agg_clip_liang_barsky.h new file mode 100644 index 0000000..4b5fedb --- /dev/null +++ b/include/agg_clip_liang_barsky.h @@ -0,0 +1,333 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Liang-Barsky clipping +// +//---------------------------------------------------------------------------- +#ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED +#define AGG_CLIP_LIANG_BARSKY_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + enum clipping_flags_e + { + clipping_flags_x1_clipped = 4, + clipping_flags_x2_clipped = 1, + clipping_flags_y1_clipped = 8, + clipping_flags_y2_clipped = 2, + clipping_flags_x_clipped = clipping_flags_x1_clipped | clipping_flags_x2_clipped, + clipping_flags_y_clipped = clipping_flags_y1_clipped | clipping_flags_y2_clipped + }; + + //----------------------------------------------------------clipping_flags + // Determine the clipping code of the vertex according to the + // Cyrus-Beck line clipping algorithm + // + // | | + // 0110 | 0010 | 0011 + // | | + // -------+--------+-------- clip_box.y2 + // | | + // 0100 | 0000 | 0001 + // | | + // -------+--------+-------- clip_box.y1 + // | | + // 1100 | 1000 | 1001 + // | | + // clip_box.x1 clip_box.x2 + // + // + template<class T> + inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box) + { + return (x > clip_box.x2) | + ((y > clip_box.y2) << 1) | + ((x < clip_box.x1) << 2) | + ((y < clip_box.y1) << 3); + } + + //--------------------------------------------------------clipping_flags_x + template<class T> + inline unsigned clipping_flags_x(T x, const rect_base<T>& clip_box) + { + return (x > clip_box.x2) | ((x < clip_box.x1) << 2); + } + + + //--------------------------------------------------------clipping_flags_y + template<class T> + inline unsigned clipping_flags_y(T y, const rect_base<T>& clip_box) + { + return ((y > clip_box.y2) << 1) | ((y < clip_box.y1) << 3); + } + + + //-------------------------------------------------------clip_liang_barsky + template<class T> + inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2, + const rect_base<T>& clip_box, + T* x, T* y) + { + const double nearzero = 1e-30; + + double deltax = x2 - x1; + double deltay = y2 - y1; + double xin; + double xout; + double yin; + double yout; + double tinx; + double tiny; + double toutx; + double touty; + double tin1; + double tin2; + double tout1; + unsigned np = 0; + + if(deltax == 0.0) + { + // bump off of the vertical + deltax = (x1 > clip_box.x1) ? -nearzero : nearzero; + } + + if(deltay == 0.0) + { + // bump off of the horizontal + deltay = (y1 > clip_box.y1) ? -nearzero : nearzero; + } + + if(deltax > 0.0) + { + // points to right + xin = clip_box.x1; + xout = clip_box.x2; + } + else + { + xin = clip_box.x2; + xout = clip_box.x1; + } + + if(deltay > 0.0) + { + // points up + yin = clip_box.y1; + yout = clip_box.y2; + } + else + { + yin = clip_box.y2; + yout = clip_box.y1; + } + + tinx = (xin - x1) / deltax; + tiny = (yin - y1) / deltay; + + if (tinx < tiny) + { + // hits x first + tin1 = tinx; + tin2 = tiny; + } + else + { + // hits y first + tin1 = tiny; + tin2 = tinx; + } + + if(tin1 <= 1.0) + { + if(0.0 < tin1) + { + *x++ = (T)xin; + *y++ = (T)yin; + ++np; + } + + if(tin2 <= 1.0) + { + toutx = (xout - x1) / deltax; + touty = (yout - y1) / deltay; + + tout1 = (toutx < touty) ? toutx : touty; + + if(tin2 > 0.0 || tout1 > 0.0) + { + if(tin2 <= tout1) + { + if(tin2 > 0.0) + { + if(tinx > tiny) + { + *x++ = (T)xin; + *y++ = (T)(y1 + tinx * deltay); + } + else + { + *x++ = (T)(x1 + tiny * deltax); + *y++ = (T)yin; + } + ++np; + } + + if(tout1 < 1.0) + { + if(toutx < touty) + { + *x++ = (T)xout; + *y++ = (T)(y1 + toutx * deltay); + } + else + { + *x++ = (T)(x1 + touty * deltax); + *y++ = (T)yout; + } + } + else + { + *x++ = x2; + *y++ = y2; + } + ++np; + } + else + { + if(tinx > tiny) + { + *x++ = (T)xin; + *y++ = (T)yout; + } + else + { + *x++ = (T)xout; + *y++ = (T)yin; + } + ++np; + } + } + } + } + return np; + } + + + //---------------------------------------------------------------------------- + template<class T> + bool clip_move_point(T x1, T y1, T x2, T y2, + const rect_base<T>& clip_box, + T* x, T* y, unsigned flags) + { + T bound; + + if(flags & clipping_flags_x_clipped) + { + if(x1 == x2) + { + return false; + } + bound = (flags & clipping_flags_x1_clipped) ? clip_box.x1 : clip_box.x2; + *y = (T)(double(bound - x1) * (y2 - y1) / (x2 - x1) + y1); + *x = bound; + } + + flags = clipping_flags_y(*y, clip_box); + if(flags & clipping_flags_y_clipped) + { + if(y1 == y2) + { + return false; + } + bound = (flags & clipping_flags_y1_clipped) ? clip_box.y1 : clip_box.y2; + *x = (T)(double(bound - y1) * (x2 - x1) / (y2 - y1) + x1); + *y = bound; + } + return true; + } + + //-------------------------------------------------------clip_line_segment + // Returns: ret >= 4 - Fully clipped + // (ret & 1) != 0 - First point has been moved + // (ret & 2) != 0 - Second point has been moved + // + template<class T> + unsigned clip_line_segment(T* x1, T* y1, T* x2, T* y2, + const rect_base<T>& clip_box) + { + unsigned f1 = clipping_flags(*x1, *y1, clip_box); + unsigned f2 = clipping_flags(*x2, *y2, clip_box); + unsigned ret = 0; + + if((f2 | f1) == 0) + { + // Fully visible + return 0; + } + + if((f1 & clipping_flags_x_clipped) != 0 && + (f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped)) + { + // Fully clipped + return 4; + } + + if((f1 & clipping_flags_y_clipped) != 0 && + (f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped)) + { + // Fully clipped + return 4; + } + + T tx1 = *x1; + T ty1 = *y1; + T tx2 = *x2; + T ty2 = *y2; + if(f1) + { + if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1)) + { + return 4; + } + if(*x1 == *x2 && *y1 == *y2) + { + return 4; + } + ret |= 1; + } + if(f2) + { + if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2)) + { + return 4; + } + if(*x1 == *x2 && *y1 == *y2) + { + return 4; + } + ret |= 2; + } + return ret; + } + + +} + + +#endif diff --git a/include/agg_color_gray.h b/include/agg_color_gray.h new file mode 100644 index 0000000..f66588c --- /dev/null +++ b/include/agg_color_gray.h @@ -0,0 +1,1047 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +// +// color types gray8, gray16 +// +//---------------------------------------------------------------------------- + +#ifndef AGG_COLOR_GRAY_INCLUDED +#define AGG_COLOR_GRAY_INCLUDED + +#include "agg_basics.h" +#include "agg_color_rgba.h" + +namespace agg +{ + + //===================================================================gray8 + template<class Colorspace> + struct gray8T + { + typedef int8u value_type; + typedef int32u calc_type; + typedef int32 long_type; + enum base_scale_e + { + base_shift = 8, + base_scale = 1 << base_shift, + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) + }; + typedef gray8T self_type; + + value_type v; + value_type a; + + static value_type luminance(const rgba& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask)); + } + + static value_type luminance(const rgba8& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type((55u * c.r + 184u * c.g + 18u * c.b) >> 8); + } + + static void convert(gray8T<linear>& dst, const gray8T<sRGB>& src) + { + dst.v = sRGB_conv<value_type>::rgb_from_sRGB(src.v); + dst.a = src.a; + } + + static void convert(gray8T<sRGB>& dst, const gray8T<linear>& src) + { + dst.v = sRGB_conv<value_type>::rgb_to_sRGB(src.v); + dst.a = src.a; + } + + static void convert(gray8T<linear>& dst, const rgba8& src) + { + dst.v = luminance(src); + dst.a = src.a; + } + + static void convert(gray8T<linear>& dst, const srgba8& src) + { + // The RGB weights are only valid for linear values. + convert(dst, rgba8(src)); + } + + static void convert(gray8T<sRGB>& dst, const rgba8& src) + { + dst.v = sRGB_conv<value_type>::rgb_to_sRGB(luminance(src)); + dst.a = src.a; + } + + static void convert(gray8T<sRGB>& dst, const srgba8& src) + { + // The RGB weights are only valid for linear values. + convert(dst, rgba8(src)); + } + + //-------------------------------------------------------------------- + gray8T() {} + + //-------------------------------------------------------------------- + explicit gray8T(unsigned v_, unsigned a_ = base_mask) : + v(int8u(v_)), a(int8u(a_)) {} + + //-------------------------------------------------------------------- + gray8T(const self_type& c, unsigned a_) : + v(c.v), a(value_type(a_)) {} + + //-------------------------------------------------------------------- + gray8T(const rgba& c) : + v(luminance(c)), + a(value_type(uround(c.a * base_mask))) {} + + //-------------------------------------------------------------------- + template<class T> + gray8T(const gray8T<T>& c) + { + convert(*this, c); + } + + //-------------------------------------------------------------------- + template<class T> + gray8T(const rgba8T<T>& c) + { + convert(*this, c); + } + + //-------------------------------------------------------------------- + template<class T> + T convert_from_sRGB() const + { + typename T::value_type y = sRGB_conv<typename T::value_type>::rgb_from_sRGB(v); + return T(y, y, y, sRGB_conv<typename T::value_type>::alpha_from_sRGB(a)); + } + + template<class T> + T convert_to_sRGB() const + { + typename T::value_type y = sRGB_conv<typename T::value_type>::rgb_to_sRGB(v); + return T(y, y, y, sRGB_conv<typename T::value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + rgba8 make_rgba8(const linear&) const + { + return rgba8(v, v, v, a); + } + + rgba8 make_rgba8(const sRGB&) const + { + return convert_from_sRGB<srgba8>(); + } + + operator rgba8() const + { + return make_rgba8(Colorspace()); + } + + //-------------------------------------------------------------------- + srgba8 make_srgba8(const linear&) const + { + return convert_to_sRGB<rgba8>(); + } + + srgba8 make_srgba8(const sRGB&) const + { + return srgba8(v, v, v, a); + } + + operator srgba8() const + { + return make_rgba8(Colorspace()); + } + + //-------------------------------------------------------------------- + rgba16 make_rgba16(const linear&) const + { + rgba16::value_type rgb = (v << 8) | v; + return rgba16(rgb, rgb, rgb, (a << 8) | a); + } + + rgba16 make_rgba16(const sRGB&) const + { + return convert_from_sRGB<rgba16>(); + } + + operator rgba16() const + { + return make_rgba16(Colorspace()); + } + + //-------------------------------------------------------------------- + rgba32 make_rgba32(const linear&) const + { + rgba32::value_type v32 = v / 255.0f; + return rgba32(v32, v32, v32, a / 255.0f); + } + + rgba32 make_rgba32(const sRGB&) const + { + return convert_from_sRGB<rgba32>(); + } + + operator rgba32() const + { + return make_rgba32(Colorspace()); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) + { + return base_mask; + } + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, value_type b) + { + return multiply(a, b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return multiply(b, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() + { + v = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = (value_type)uround(a_ * double(base_mask)); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / double(base_mask); + } + + //-------------------------------------------------------------------- + self_type& premultiply() + { + if (a < base_mask) + { + if (a == 0) v = 0; + else v = multiply(v, a); + } + return *this; + } + + //-------------------------------------------------------------------- + self_type& demultiply() + { + if (a < base_mask) + { + if (a == 0) + { + v = 0; + } + else + { + calc_type v_ = (calc_type(v) * base_mask) / a; + v = value_type((v_ > base_mask) ? (value_type)base_mask : v_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + self_type gradient(self_type c, double k) const + { + self_type ret; + calc_type ik = uround(k * base_scale); + ret.v = lerp(v, c.v, ik); + ret.a = lerp(a, c.a, ik); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + calc_type cv, ca; + if (cover == cover_mask) + { + if (c.a == base_mask) + { + *this = c; + return; + } + else + { + cv = v + c.v; + ca = a + c.a; + } + } + else + { + cv = v + mult_cover(c.v, cover); + ca = a + mult_cover(c.a, cover); + } + v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0); } + }; + + typedef gray8T<linear> gray8; + typedef gray8T<sRGB> sgray8; + + + //==================================================================gray16 + struct gray16 + { + typedef int16u value_type; + typedef int32u calc_type; + typedef int64 long_type; + enum base_scale_e + { + base_shift = 16, + base_scale = 1 << base_shift, + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) + }; + typedef gray16 self_type; + + value_type v; + value_type a; + + static value_type luminance(const rgba& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask)); + } + + static value_type luminance(const rgba16& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type((13933u * c.r + 46872u * c.g + 4732u * c.b) >> 16); + } + + static value_type luminance(const rgba8& c) + { + return luminance(rgba16(c)); + } + + static value_type luminance(const srgba8& c) + { + return luminance(rgba16(c)); + } + + static value_type luminance(const rgba32& c) + { + return luminance(rgba(c)); + } + + //-------------------------------------------------------------------- + gray16() {} + + //-------------------------------------------------------------------- + explicit gray16(unsigned v_, unsigned a_ = base_mask) : + v(int16u(v_)), a(int16u(a_)) {} + + //-------------------------------------------------------------------- + gray16(const self_type& c, unsigned a_) : + v(c.v), a(value_type(a_)) {} + + //-------------------------------------------------------------------- + gray16(const rgba& c) : + v(luminance(c)), + a((value_type)uround(c.a * double(base_mask))) {} + + //-------------------------------------------------------------------- + gray16(const rgba8& c) : + v(luminance(c)), + a((value_type(c.a) << 8) | c.a) {} + + //-------------------------------------------------------------------- + gray16(const srgba8& c) : + v(luminance(c)), + a((value_type(c.a) << 8) | c.a) {} + + //-------------------------------------------------------------------- + gray16(const rgba16& c) : + v(luminance(c)), + a(c.a) {} + + //-------------------------------------------------------------------- + gray16(const gray8& c) : + v((value_type(c.v) << 8) | c.v), + a((value_type(c.a) << 8) | c.a) {} + + //-------------------------------------------------------------------- + gray16(const sgray8& c) : + v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)), + a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + operator rgba8() const + { + return rgba8(v >> 8, v >> 8, v >> 8, a >> 8); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + value_type y = sRGB_conv<value_type>::rgb_to_sRGB(v); + return srgba8(y, y, y, sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator rgba16() const + { + return rgba16(v, v, v, a); + } + + //-------------------------------------------------------------------- + operator rgba32() const + { + rgba32::value_type v32 = v / 65535.0f; + return rgba32(v32, v32, v32, a / 65535.0f); + } + + //-------------------------------------------------------------------- + operator gray8() const + { + return gray8(v >> 8, a >> 8); + } + + //-------------------------------------------------------------------- + operator sgray8() const + { + return sgray8( + sRGB_conv<value_type>::rgb_to_sRGB(v), + sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int16u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) + { + return base_mask; + } + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, almost exact over int16u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return multiply(a, b << 8 | b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return mult_cover(b, a) >> 8; + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() + { + v = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if(a_ > 1) a = 1; + else a = (value_type)uround(a_ * double(base_mask)); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / double(base_mask); + } + + + //-------------------------------------------------------------------- + self_type& premultiply() + { + if (a < base_mask) + { + if(a == 0) v = 0; + else v = multiply(v, a); + } + return *this; + } + + //-------------------------------------------------------------------- + self_type& demultiply() + { + if (a < base_mask) + { + if (a == 0) + { + v = 0; + } + else + { + calc_type v_ = (calc_type(v) * base_mask) / a; + v = (v_ > base_mask) ? value_type(base_mask) : value_type(v_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + self_type gradient(self_type c, double k) const + { + self_type ret; + calc_type ik = uround(k * base_scale); + ret.v = lerp(v, c.v, ik); + ret.a = lerp(a, c.a, ik); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + calc_type cv, ca; + if (cover == cover_mask) + { + if (c.a == base_mask) + { + *this = c; + return; + } + else + { + cv = v + c.v; + ca = a + c.a; + } + } + else + { + cv = v + mult_cover(c.v, cover); + ca = a + mult_cover(c.a, cover); + } + v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0); } + }; + + + //===================================================================gray32 + struct gray32 + { + typedef float value_type; + typedef double calc_type; + typedef double long_type; + typedef gray32 self_type; + + value_type v; + value_type a; + + // Calculate grayscale value as per ITU-R BT.709. + static value_type luminance(double r, double g, double b) + { + return value_type(0.2126 * r + 0.7152 * g + 0.0722 * b); + } + + static value_type luminance(const rgba& c) + { + return luminance(c.r, c.g, c.b); + } + + static value_type luminance(const rgba32& c) + { + return luminance(c.r, c.g, c.b); + } + + static value_type luminance(const rgba8& c) + { + return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0); + } + + static value_type luminance(const rgba16& c) + { + return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0); + } + + //-------------------------------------------------------------------- + gray32() {} + + //-------------------------------------------------------------------- + explicit gray32(value_type v_, value_type a_ = 1) : + v(v_), a(a_) {} + + //-------------------------------------------------------------------- + gray32(const self_type& c, value_type a_) : + v(c.v), a(a_) {} + + //-------------------------------------------------------------------- + gray32(const rgba& c) : + v(luminance(c)), + a(value_type(c.a)) {} + + //-------------------------------------------------------------------- + gray32(const rgba8& c) : + v(luminance(c)), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + gray32(const srgba8& c) : + v(luminance(rgba32(c))), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + gray32(const rgba16& c) : + v(luminance(c)), + a(value_type(c.a / 65535.0)) {} + + //-------------------------------------------------------------------- + gray32(const rgba32& c) : + v(luminance(c)), + a(value_type(c.a)) {} + + //-------------------------------------------------------------------- + gray32(const gray8& c) : + v(value_type(c.v / 255.0)), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + gray32(const sgray8& c) : + v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)), + a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + gray32(const gray16& c) : + v(value_type(c.v / 65535.0)), + a(value_type(c.a / 65535.0)) {} + + //-------------------------------------------------------------------- + operator rgba() const + { + return rgba(v, v, v, a); + } + + //-------------------------------------------------------------------- + operator gray8() const + { + return gray8(uround(v * 255.0), uround(a * 255.0)); + } + + //-------------------------------------------------------------------- + operator sgray8() const + { + // Return (non-premultiplied) sRGB values. + return sgray8( + sRGB_conv<value_type>::rgb_to_sRGB(v), + sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator gray16() const + { + return gray16(uround(v * 65535.0), uround(a * 65535.0)); + } + + //-------------------------------------------------------------------- + operator rgba8() const + { + rgba8::value_type y = uround(v * 255.0); + return rgba8(y, y, y, uround(a * 255.0)); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + srgba8::value_type y = sRGB_conv<value_type>::rgb_to_sRGB(v); + return srgba8(y, y, y, sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator rgba16() const + { + rgba16::value_type y = uround(v * 65535.0); + return rgba16(y, y, y, uround(a * 65535.0)); + } + + //-------------------------------------------------------------------- + operator rgba32() const + { + return rgba32(v, v, v, a); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(a); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return 1; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a <= 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a >= 1; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return 1 - x; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + return value_type(a * b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + return (b == 0) ? 0 : value_type(a / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return n > 0 ? a / (1 << n) : a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return value_type(a * b / cover_mask); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return cover_type(uround(a * b)); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return (1 - a) * p + q; // more accurate than "p + q - p * a" + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + // The form "p + a * (q - p)" avoids a multiplication, but may produce an + // inaccurate result. For example, "p + (q - p)" may not be exactly equal + // to q. Therefore, stick to the basic expression, which at least produces + // the correct result at either extreme. + return (1 - a) * p + a * q; + } + + //-------------------------------------------------------------------- + self_type& clear() + { + v = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = value_type(a_); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return a; + } + + + //-------------------------------------------------------------------- + self_type& premultiply() + { + if (a < 0) v = 0; + else if(a < 1) v *= a; + return *this; + } + + //-------------------------------------------------------------------- + self_type& demultiply() + { + if (a < 0) v = 0; + else if (a < 1) v /= a; + return *this; + } + + //-------------------------------------------------------------------- + self_type gradient(self_type c, double k) const + { + return self_type( + value_type(v + (c.v - v) * k), + value_type(a + (c.a - a) * k)); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0); } + }; +} + + + + +#endif diff --git a/include/agg_color_rgba.h b/include/agg_color_rgba.h new file mode 100644 index 0000000..0f5ab8a --- /dev/null +++ b/include/agg_color_rgba.h @@ -0,0 +1,1353 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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. +// +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- + +#ifndef AGG_COLOR_RGBA_INCLUDED +#define AGG_COLOR_RGBA_INCLUDED + +#include <cmath> +#include "agg_basics.h" +#include "agg_gamma_lut.h" + +namespace agg +{ + // Supported component orders for RGB and RGBA pixel formats + //======================================================================= + struct order_rgb { enum rgb_e { R=0, G=1, B=2, N=3 }; }; + struct order_bgr { enum bgr_e { B=0, G=1, R=2, N=3 }; }; + struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, N=4 }; }; + struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, N=4 }; }; + struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, N=4 }; }; + struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, N=4 }; }; + + // Colorspace tag types. + struct linear {}; + struct sRGB {}; + + //====================================================================rgba + struct rgba + { + typedef double value_type; + + double r; + double g; + double b; + double a; + + //-------------------------------------------------------------------- + rgba() {} + + //-------------------------------------------------------------------- + rgba(double r_, double g_, double b_, double a_=1.0) : + r(r_), g(g_), b(b_), a(a_) {} + + //-------------------------------------------------------------------- + rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {} + + //-------------------------------------------------------------------- + rgba& clear() + { + r = g = b = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + rgba& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + rgba& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = a_; + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return a; + } + + //-------------------------------------------------------------------- + rgba& premultiply() + { + r *= a; + g *= a; + b *= a; + return *this; + } + + //-------------------------------------------------------------------- + rgba& premultiply(double a_) + { + if (a <= 0 || a_ <= 0) + { + r = g = b = a = 0; + } + else + { + a_ /= a; + r *= a_; + g *= a_; + b *= a_; + a = a_; + } + return *this; + } + + //-------------------------------------------------------------------- + rgba& demultiply() + { + if (a == 0) + { + r = g = b = 0; + } + else + { + double a_ = 1.0 / a; + r *= a_; + g *= a_; + b *= a_; + } + return *this; + } + + + //-------------------------------------------------------------------- + rgba gradient(rgba c, double k) const + { + rgba ret; + ret.r = r + (c.r - r) * k; + ret.g = g + (c.g - g) * k; + ret.b = b + (c.b - b) * k; + ret.a = a + (c.a - a) * k; + return ret; + } + + rgba& operator+=(const rgba& c) + { + r += c.r; + g += c.g; + b += c.b; + a += c.a; + return *this; + } + + rgba& operator*=(double k) + { + r *= k; + g *= k; + b *= k; + a *= k; + return *this; + } + + //-------------------------------------------------------------------- + static rgba no_color() { return rgba(0,0,0,0); } + + //-------------------------------------------------------------------- + static rgba from_wavelength(double wl, double gamma = 1.0); + + //-------------------------------------------------------------------- + explicit rgba(double wavelen, double gamma=1.0) + { + *this = from_wavelength(wavelen, gamma); + } + + }; + + inline rgba operator+(const rgba& a, const rgba& b) + { + return rgba(a) += b; + } + + inline rgba operator*(const rgba& a, double b) + { + return rgba(a) *= b; + } + + //------------------------------------------------------------------------ + inline rgba rgba::from_wavelength(double wl, double gamma) + { + rgba t(0.0, 0.0, 0.0); + + if (wl >= 380.0 && wl <= 440.0) + { + t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0); + t.b = 1.0; + } + else if (wl >= 440.0 && wl <= 490.0) + { + t.g = (wl - 440.0) / (490.0 - 440.0); + t.b = 1.0; + } + else if (wl >= 490.0 && wl <= 510.0) + { + t.g = 1.0; + t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0); + } + else if (wl >= 510.0 && wl <= 580.0) + { + t.r = (wl - 510.0) / (580.0 - 510.0); + t.g = 1.0; + } + else if (wl >= 580.0 && wl <= 645.0) + { + t.r = 1.0; + t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0); + } + else if (wl >= 645.0 && wl <= 780.0) + { + t.r = 1.0; + } + + double s = 1.0; + if (wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0); + else if (wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0); + + t.r = std::pow(t.r * s, gamma); + t.g = std::pow(t.g * s, gamma); + t.b = std::pow(t.b * s, gamma); + return t; + } + + inline rgba rgba_pre(double r, double g, double b, double a) + { + return rgba(r, g, b, a).premultiply(); + } + + + //===================================================================rgba8 + template<class Colorspace> + struct rgba8T + { + typedef int8u value_type; + typedef int32u calc_type; + typedef int32 long_type; + enum base_scale_e + { + base_shift = 8, + base_scale = 1 << base_shift, + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) + }; + typedef rgba8T self_type; + + + value_type r; + value_type g; + value_type b; + value_type a; + + static void convert(rgba8T<linear>& dst, const rgba8T<sRGB>& src) + { + dst.r = sRGB_conv<value_type>::rgb_from_sRGB(src.r); + dst.g = sRGB_conv<value_type>::rgb_from_sRGB(src.g); + dst.b = sRGB_conv<value_type>::rgb_from_sRGB(src.b); + dst.a = src.a; + } + + static void convert(rgba8T<sRGB>& dst, const rgba8T<linear>& src) + { + dst.r = sRGB_conv<value_type>::rgb_to_sRGB(src.r); + dst.g = sRGB_conv<value_type>::rgb_to_sRGB(src.g); + dst.b = sRGB_conv<value_type>::rgb_to_sRGB(src.b); + dst.a = src.a; + } + + static void convert(rgba8T<linear>& dst, const rgba& src) + { + dst.r = value_type(uround(src.r * base_mask)); + dst.g = value_type(uround(src.g * base_mask)); + dst.b = value_type(uround(src.b * base_mask)); + dst.a = value_type(uround(src.a * base_mask)); + } + + static void convert(rgba8T<sRGB>& dst, const rgba& src) + { + // Use the "float" table. + dst.r = sRGB_conv<float>::rgb_to_sRGB(float(src.r)); + dst.g = sRGB_conv<float>::rgb_to_sRGB(float(src.g)); + dst.b = sRGB_conv<float>::rgb_to_sRGB(float(src.b)); + dst.a = sRGB_conv<float>::alpha_to_sRGB(float(src.a)); + } + + static void convert(rgba& dst, const rgba8T<linear>& src) + { + dst.r = src.r / 255.0; + dst.g = src.g / 255.0; + dst.b = src.b / 255.0; + dst.a = src.a / 255.0; + } + + static void convert(rgba& dst, const rgba8T<sRGB>& src) + { + // Use the "float" table. + dst.r = sRGB_conv<float>::rgb_from_sRGB(src.r); + dst.g = sRGB_conv<float>::rgb_from_sRGB(src.g); + dst.b = sRGB_conv<float>::rgb_from_sRGB(src.b); + dst.a = sRGB_conv<float>::alpha_from_sRGB(src.a); + } + + //-------------------------------------------------------------------- + rgba8T() {} + + //-------------------------------------------------------------------- + rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask) : + r(value_type(r_)), + g(value_type(g_)), + b(value_type(b_)), + a(value_type(a_)) {} + + //-------------------------------------------------------------------- + rgba8T(const rgba& c) + { + convert(*this, c); + } + + //-------------------------------------------------------------------- + rgba8T(const self_type& c, unsigned a_) : + r(c.r), g(c.g), b(c.b), a(value_type(a_)) {} + + //-------------------------------------------------------------------- + template<class T> + rgba8T(const rgba8T<T>& c) + { + convert(*this, c); + } + + //-------------------------------------------------------------------- + operator rgba() const + { + rgba c; + convert(c, *this); + return c; + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return base_mask - x; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) + { + return base_mask; + } + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return multiply(a, b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return multiply(b, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() + { + r = g = b = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = (value_type)uround(a_ * double(base_mask)); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / double(base_mask); + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply() + { + if (a != base_mask) + { + if (a == 0) + { + r = g = b = 0; + } + else + { + r = multiply(r, a); + g = multiply(g, a); + b = multiply(b, a); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply(unsigned a_) + { + if (a != base_mask || a_ < base_mask) + { + if (a == 0 || a_ == 0) + { + r = g = b = a = 0; + } + else + { + calc_type r_ = (calc_type(r) * a_) / a; + calc_type g_ = (calc_type(g) * a_) / a; + calc_type b_ = (calc_type(b) * a_) / a; + r = value_type((r_ > a_) ? a_ : r_); + g = value_type((g_ > a_) ? a_ : g_); + b = value_type((b_ > a_) ? a_ : b_); + a = value_type(a_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& demultiply() + { + if (a < base_mask) + { + if (a == 0) + { + r = g = b = 0; + } + else + { + calc_type r_ = (calc_type(r) * base_mask) / a; + calc_type g_ = (calc_type(g) * base_mask) / a; + calc_type b_ = (calc_type(b) * base_mask) / a; + r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); + g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); + b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type gradient(const self_type& c, double k) const + { + self_type ret; + calc_type ik = uround(k * base_mask); + ret.r = lerp(r, c.r, ik); + ret.g = lerp(g, c.g, ik); + ret.b = lerp(b, c.b, ik); + ret.a = lerp(a, c.a, ik); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + calc_type cr, cg, cb, ca; + if (cover == cover_mask) + { + if (c.a == base_mask) + { + *this = c; + return; + } + else + { + cr = r + c.r; + cg = g + c.g; + cb = b + c.b; + ca = a + c.a; + } + } + else + { + cr = r + mult_cover(c.r, cover); + cg = g + mult_cover(c.g, cover); + cb = b + mult_cover(c.b, cover); + ca = a + mult_cover(c.a, cover); + } + r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr); + g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg); + b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) + { + r = gamma.dir(r); + g = gamma.dir(g); + b = gamma.dir(b); + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) + { + r = gamma.inv(r); + g = gamma.inv(g); + b = gamma.inv(b); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0,0,0); } + + //-------------------------------------------------------------------- + static self_type from_wavelength(double wl, double gamma = 1.0) + { + return self_type(rgba::from_wavelength(wl, gamma)); + } + }; + + typedef rgba8T<linear> rgba8; + typedef rgba8T<sRGB> srgba8; + + + //-------------------------------------------------------------rgb8_packed + inline rgba8 rgb8_packed(unsigned v) + { + return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); + } + + //-------------------------------------------------------------bgr8_packed + inline rgba8 bgr8_packed(unsigned v) + { + return rgba8(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF); + } + + //------------------------------------------------------------argb8_packed + inline rgba8 argb8_packed(unsigned v) + { + return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF, v >> 24); + } + + //---------------------------------------------------------rgba8_gamma_dir + template<class GammaLUT> + rgba8 rgba8_gamma_dir(rgba8 c, const GammaLUT& gamma) + { + return rgba8(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a); + } + + //---------------------------------------------------------rgba8_gamma_inv + template<class GammaLUT> + rgba8 rgba8_gamma_inv(rgba8 c, const GammaLUT& gamma) + { + return rgba8(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a); + } + + + + //==================================================================rgba16 + struct rgba16 + { + typedef int16u value_type; + typedef int32u calc_type; + typedef int64 long_type; + enum base_scale_e + { + base_shift = 16, + base_scale = 1 << base_shift, + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) + }; + typedef rgba16 self_type; + + value_type r; + value_type g; + value_type b; + value_type a; + + //-------------------------------------------------------------------- + rgba16() {} + + //-------------------------------------------------------------------- + rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) : + r(value_type(r_)), + g(value_type(g_)), + b(value_type(b_)), + a(value_type(a_)) {} + + //-------------------------------------------------------------------- + rgba16(const self_type& c, unsigned a_) : + r(c.r), g(c.g), b(c.b), a(value_type(a_)) {} + + //-------------------------------------------------------------------- + rgba16(const rgba& c) : + r((value_type)uround(c.r * double(base_mask))), + g((value_type)uround(c.g * double(base_mask))), + b((value_type)uround(c.b * double(base_mask))), + a((value_type)uround(c.a * double(base_mask))) {} + + //-------------------------------------------------------------------- + rgba16(const rgba8& c) : + r(value_type((value_type(c.r) << 8) | c.r)), + g(value_type((value_type(c.g) << 8) | c.g)), + b(value_type((value_type(c.b) << 8) | c.b)), + a(value_type((value_type(c.a) << 8) | c.a)) {} + + //-------------------------------------------------------------------- + rgba16(const srgba8& c) : + r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)), + g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)), + b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)), + a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + operator rgba() const + { + return rgba( + r / 65535.0, + g / 65535.0, + b / 65535.0, + a / 65535.0); + } + + //-------------------------------------------------------------------- + operator rgba8() const + { + return rgba8(r >> 8, g >> 8, b >> 8, a >> 8); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + // Return (non-premultiplied) sRGB values. + return srgba8( + sRGB_conv<value_type>::rgb_to_sRGB(r), + sRGB_conv<value_type>::rgb_to_sRGB(g), + sRGB_conv<value_type>::rgb_to_sRGB(b), + sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return base_mask - x; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int16u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) + { + return base_mask; + } + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, almost exact over int16u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return multiply(a, (b << 8) | b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return multiply((a << 8) | a, b) >> 8; + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() + { + r = g = b = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + if (a_ > 1) a = 1; + a = value_type(uround(a_ * double(base_mask))); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / double(base_mask); + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply() + { + if (a != base_mask) + { + if (a == 0) + { + r = g = b = 0; + } + else + { + r = multiply(r, a); + g = multiply(g, a); + b = multiply(b, a); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply(unsigned a_) + { + if (a < base_mask || a_ < base_mask) + { + if (a == 0 || a_ == 0) + { + r = g = b = a = 0; + } + else + { + calc_type r_ = (calc_type(r) * a_) / a; + calc_type g_ = (calc_type(g) * a_) / a; + calc_type b_ = (calc_type(b) * a_) / a; + r = value_type((r_ > a_) ? a_ : r_); + g = value_type((g_ > a_) ? a_ : g_); + b = value_type((b_ > a_) ? a_ : b_); + a = value_type(a_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& demultiply() + { + if (a < base_mask) + { + if (a == 0) + { + r = g = b = 0; + } + else + { + calc_type r_ = (calc_type(r) * base_mask) / a; + calc_type g_ = (calc_type(g) * base_mask) / a; + calc_type b_ = (calc_type(b) * base_mask) / a; + r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); + g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); + b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type gradient(const self_type& c, double k) const + { + self_type ret; + calc_type ik = uround(k * base_mask); + ret.r = lerp(r, c.r, ik); + ret.g = lerp(g, c.g, ik); + ret.b = lerp(b, c.b, ik); + ret.a = lerp(a, c.a, ik); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + calc_type cr, cg, cb, ca; + if (cover == cover_mask) + { + if (c.a == base_mask) + { + *this = c; + return; + } + else + { + cr = r + c.r; + cg = g + c.g; + cb = b + c.b; + ca = a + c.a; + } + } + else + { + cr = r + mult_cover(c.r, cover); + cg = g + mult_cover(c.g, cover); + cb = b + mult_cover(c.b, cover); + ca = a + mult_cover(c.a, cover); + } + r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr); + g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg); + b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) + { + r = gamma.dir(r); + g = gamma.dir(g); + b = gamma.dir(b); + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) + { + r = gamma.inv(r); + g = gamma.inv(g); + b = gamma.inv(b); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0,0,0); } + + //-------------------------------------------------------------------- + static self_type from_wavelength(double wl, double gamma = 1.0) + { + return self_type(rgba::from_wavelength(wl, gamma)); + } + }; + + + //------------------------------------------------------rgba16_gamma_dir + template<class GammaLUT> + rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma) + { + return rgba16(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a); + } + + //------------------------------------------------------rgba16_gamma_inv + template<class GammaLUT> + rgba16 rgba16_gamma_inv(rgba16 c, const GammaLUT& gamma) + { + return rgba16(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a); + } + + //====================================================================rgba32 + struct rgba32 + { + typedef float value_type; + typedef double calc_type; + typedef double long_type; + typedef rgba32 self_type; + + value_type r; + value_type g; + value_type b; + value_type a; + + //-------------------------------------------------------------------- + rgba32() {} + + //-------------------------------------------------------------------- + rgba32(value_type r_, value_type g_, value_type b_, value_type a_= 1) : + r(r_), g(g_), b(b_), a(a_) {} + + //-------------------------------------------------------------------- + rgba32(const self_type& c, float a_) : + r(c.r), g(c.g), b(c.b), a(a_) {} + + //-------------------------------------------------------------------- + rgba32(const rgba& c) : + r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {} + + //-------------------------------------------------------------------- + rgba32(const rgba8& c) : + r(value_type(c.r / 255.0)), + g(value_type(c.g / 255.0)), + b(value_type(c.b / 255.0)), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + rgba32(const srgba8& c) : + r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)), + g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)), + b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)), + a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + rgba32(const rgba16& c) : + r(value_type(c.r / 65535.0)), + g(value_type(c.g / 65535.0)), + b(value_type(c.b / 65535.0)), + a(value_type(c.a / 65535.0)) {} + + //-------------------------------------------------------------------- + operator rgba() const + { + return rgba(r, g, b, a); + } + + //-------------------------------------------------------------------- + operator rgba8() const + { + return rgba8( + uround(r * 255.0), + uround(g * 255.0), + uround(b * 255.0), + uround(a * 255.0)); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + return srgba8( + sRGB_conv<value_type>::rgb_to_sRGB(r), + sRGB_conv<value_type>::rgb_to_sRGB(g), + sRGB_conv<value_type>::rgb_to_sRGB(b), + sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator rgba16() const + { + return rgba8( + uround(r * 65535.0), + uround(g * 65535.0), + uround(b * 65535.0), + uround(a * 65535.0)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(a); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return 1; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a <= 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a >= 1; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return 1 - x; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + return value_type(a * b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + return (b == 0) ? 0 : value_type(a / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return n > 0 ? a / (1 << n) : a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return value_type(a * b / cover_mask); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return cover_type(uround(a * b)); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return (1 - a) * p + q; // more accurate than "p + q - p * a" + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + // The form "p + a * (q - p)" avoids a multiplication, but may produce an + // inaccurate result. For example, "p + (q - p)" may not be exactly equal + // to q. Therefore, stick to the basic expression, which at least produces + // the correct result at either extreme. + return (1 - a) * p + a * q; + } + + //-------------------------------------------------------------------- + self_type& clear() + { + r = g = b = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = value_type(a_); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return a; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply() + { + if (a < 1) + { + if (a <= 0) + { + r = g = b = 0; + } + else + { + r *= a; + g *= a; + b *= a; + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& demultiply() + { + if (a < 1) + { + if (a <= 0) + { + r = g = b = 0; + } + else + { + r /= a; + g /= a; + b /= a; + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type gradient(const self_type& c, double k) const + { + self_type ret; + ret.r = value_type(r + (c.r - r) * k); + ret.g = value_type(g + (c.g - g) * k); + ret.b = value_type(b + (c.b - b) * k); + ret.a = value_type(a + (c.a - a) * k); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + if (cover == cover_mask) + { + if (c.is_opaque()) + { + *this = c; + return; + } + else + { + r += c.r; + g += c.g; + b += c.b; + a += c.a; + } + } + else + { + r += mult_cover(c.r, cover); + g += mult_cover(c.g, cover); + b += mult_cover(c.b, cover); + a += mult_cover(c.a, cover); + } + if (a > 1) a = 1; + if (r > a) r = a; + if (g > a) g = a; + if (b > a) b = a; + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) + { + r = gamma.dir(r); + g = gamma.dir(g); + b = gamma.dir(b); + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) + { + r = gamma.inv(r); + g = gamma.inv(g); + b = gamma.inv(b); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0,0,0); } + + //-------------------------------------------------------------------- + static self_type from_wavelength(double wl, double gamma = 1) + { + return self_type(rgba::from_wavelength(wl, gamma)); + } + }; +} + + + +#endif diff --git a/include/agg_config.h b/include/agg_config.h new file mode 100644 index 0000000..fa1dae2 --- /dev/null +++ b/include/agg_config.h @@ -0,0 +1,44 @@ +#ifndef AGG_CONFIG_INCLUDED +#define AGG_CONFIG_INCLUDED + +// This file can be used to redefine certain data types. + +//--------------------------------------- +// 1. Default basic types such as: +// +// AGG_INT8 +// AGG_INT8U +// AGG_INT16 +// AGG_INT16U +// AGG_INT32 +// AGG_INT32U +// AGG_INT64 +// AGG_INT64U +// +// Just replace this file with new defines if necessary. +// For example, if your compiler doesn't have a 64 bit integer type +// you can still use AGG if you define the follows: +// +// #define AGG_INT64 int +// #define AGG_INT64U unsigned +// +// It will result in overflow in 16 bit-per-component image/pattern resampling +// but it won't result any crash and the rest of the library will remain +// fully functional. + + +//--------------------------------------- +// 2. Default rendering_buffer type. Can be: +// +// Provides faster access for massive pixel operations, +// such as blur, image filtering: +// #define AGG_RENDERING_BUFFER row_ptr_cache<int8u> +// +// Provides cheaper creation and destruction (no mem allocs): +// #define AGG_RENDERING_BUFFER row_accessor<int8u> +// +// You can still use both of them simultaneously in your applications +// This #define is used only for default rendering_buffer type, +// in short hand typedefs like pixfmt_rgba32. + +#endif diff --git a/include/agg_conv_adaptor_vcgen.h b/include/agg_conv_adaptor_vcgen.h new file mode 100644 index 0000000..a79f220 --- /dev/null +++ b/include/agg_conv_adaptor_vcgen.h @@ -0,0 +1,157 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_ADAPTOR_VCGEN_INCLUDED +#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //------------------------------------------------------------null_markers + struct null_markers + { + void remove_all() {} + void add_vertex(double, double, unsigned) {} + void prepare_src() {} + + void rewind(unsigned) {} + unsigned vertex(double*, double*) { return path_cmd_stop; } + }; + + + //------------------------------------------------------conv_adaptor_vcgen + template<class VertexSource, + class Generator, + class Markers=null_markers> class conv_adaptor_vcgen + { + enum status + { + initial, + accumulate, + generate + }; + + public: + explicit conv_adaptor_vcgen(VertexSource& source) : + m_source(&source), + m_status(initial) + {} + void attach(VertexSource& source) { m_source = &source; } + + Generator& generator() { return m_generator; } + const Generator& generator() const { return m_generator; } + + Markers& markers() { return m_markers; } + const Markers& markers() const { return m_markers; } + + void rewind(unsigned path_id) + { + m_source->rewind(path_id); + m_status = initial; + } + + unsigned vertex(double* x, double* y); + + private: + // Prohibit copying + conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&); + const conv_adaptor_vcgen<VertexSource, Generator, Markers>& + operator = (const conv_adaptor_vcgen<VertexSource, Generator, Markers>&); + + VertexSource* m_source; + Generator m_generator; + Markers m_markers; + status m_status; + unsigned m_last_cmd; + double m_start_x; + double m_start_y; + }; + + + + + + //------------------------------------------------------------------------ + template<class VertexSource, class Generator, class Markers> + unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + bool done = false; + while(!done) + { + switch(m_status) + { + case initial: + m_markers.remove_all(); + m_last_cmd = m_source->vertex(&m_start_x, &m_start_y); + m_status = accumulate; + + case accumulate: + if(is_stop(m_last_cmd)) return path_cmd_stop; + + m_generator.remove_all(); + m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to); + m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to); + + for(;;) + { + cmd = m_source->vertex(x, y); + if(is_vertex(cmd)) + { + m_last_cmd = cmd; + if(is_move_to(cmd)) + { + m_start_x = *x; + m_start_y = *y; + break; + } + m_generator.add_vertex(*x, *y, cmd); + m_markers.add_vertex(*x, *y, path_cmd_line_to); + } + else + { + if(is_stop(cmd)) + { + m_last_cmd = path_cmd_stop; + break; + } + if(is_end_poly(cmd)) + { + m_generator.add_vertex(*x, *y, cmd); + break; + } + } + } + m_generator.rewind(0); + m_status = generate; + + case generate: + cmd = m_generator.vertex(x, y); + if(is_stop(cmd)) + { + m_status = accumulate; + break; + } + done = true; + break; + } + } + return cmd; + } + +} + +#endif diff --git a/include/agg_conv_adaptor_vpgen.h b/include/agg_conv_adaptor_vpgen.h new file mode 100644 index 0000000..d6b545e --- /dev/null +++ b/include/agg_conv_adaptor_vpgen.h @@ -0,0 +1,159 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_ADAPTOR_VPGEN_INCLUDED +#define AGG_CONV_ADAPTOR_VPGEN_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //======================================================conv_adaptor_vpgen + template<class VertexSource, class VPGen> class conv_adaptor_vpgen + { + public: + explicit conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {} + void attach(VertexSource& source) { m_source = &source; } + + VPGen& vpgen() { return m_vpgen; } + const VPGen& vpgen() const { return m_vpgen; } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&); + const conv_adaptor_vpgen<VertexSource, VPGen>& + operator = (const conv_adaptor_vpgen<VertexSource, VPGen>&); + + VertexSource* m_source; + VPGen m_vpgen; + double m_start_x; + double m_start_y; + unsigned m_poly_flags; + int m_vertices; + }; + + + + //------------------------------------------------------------------------ + template<class VertexSource, class VPGen> + void conv_adaptor_vpgen<VertexSource, VPGen>::rewind(unsigned path_id) + { + m_source->rewind(path_id); + m_vpgen.reset(); + m_start_x = 0; + m_start_y = 0; + m_poly_flags = 0; + m_vertices = 0; + } + + + //------------------------------------------------------------------------ + template<class VertexSource, class VPGen> + unsigned conv_adaptor_vpgen<VertexSource, VPGen>::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + for(;;) + { + cmd = m_vpgen.vertex(x, y); + if(!is_stop(cmd)) break; + + if(m_poly_flags && !m_vpgen.auto_unclose()) + { + *x = 0.0; + *y = 0.0; + cmd = m_poly_flags; + m_poly_flags = 0; + break; + } + + if(m_vertices < 0) + { + if(m_vertices < -1) + { + m_vertices = 0; + return path_cmd_stop; + } + m_vpgen.move_to(m_start_x, m_start_y); + m_vertices = 1; + continue; + } + + double tx, ty; + cmd = m_source->vertex(&tx, &ty); + if(is_vertex(cmd)) + { + if(is_move_to(cmd)) + { + if(m_vpgen.auto_close() && m_vertices > 2) + { + m_vpgen.line_to(m_start_x, m_start_y); + m_poly_flags = path_cmd_end_poly | path_flags_close; + m_start_x = tx; + m_start_y = ty; + m_vertices = -1; + continue; + } + m_vpgen.move_to(tx, ty); + m_start_x = tx; + m_start_y = ty; + m_vertices = 1; + } + else + { + m_vpgen.line_to(tx, ty); + ++m_vertices; + } + } + else + { + if(is_end_poly(cmd)) + { + m_poly_flags = cmd; + if(is_closed(cmd) || m_vpgen.auto_close()) + { + if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close; + if(m_vertices > 2) + { + m_vpgen.line_to(m_start_x, m_start_y); + } + m_vertices = 0; + } + } + else + { + // path_cmd_stop + if(m_vpgen.auto_close() && m_vertices > 2) + { + m_vpgen.line_to(m_start_x, m_start_y); + m_poly_flags = path_cmd_end_poly | path_flags_close; + m_vertices = -2; + continue; + } + break; + } + } + } + return cmd; + } + + +} + + +#endif + diff --git a/include/agg_conv_bspline.h b/include/agg_conv_bspline.h new file mode 100644 index 0000000..13d22d9 --- /dev/null +++ b/include/agg_conv_bspline.h @@ -0,0 +1,48 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_BSPLINE_INCLUDED +#define AGG_CONV_BSPLINE_INCLUDED + +#include "agg_basics.h" +#include "agg_vcgen_bspline.h" +#include "agg_conv_adaptor_vcgen.h" + + +namespace agg +{ + + //---------------------------------------------------------conv_bspline + template<class VertexSource> + struct conv_bspline : public conv_adaptor_vcgen<VertexSource, vcgen_bspline> + { + typedef conv_adaptor_vcgen<VertexSource, vcgen_bspline> base_type; + + conv_bspline(VertexSource& vs) : + conv_adaptor_vcgen<VertexSource, vcgen_bspline>(vs) {} + + void interpolation_step(double v) { base_type::generator().interpolation_step(v); } + double interpolation_step() const { return base_type::generator().interpolation_step(); } + + private: + conv_bspline(const conv_bspline<VertexSource>&); + const conv_bspline<VertexSource>& + operator = (const conv_bspline<VertexSource>&); + }; + +} + + +#endif + diff --git a/include/agg_conv_clip_polygon.h b/include/agg_conv_clip_polygon.h new file mode 100644 index 0000000..8753763 --- /dev/null +++ b/include/agg_conv_clip_polygon.h @@ -0,0 +1,63 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Polygon clipping converter +// There an optimized Liang-Basky algorithm is used. +// The algorithm doesn't optimize the degenerate edges, i.e. it will never +// break a closed polygon into two or more ones, instead, there will be +// degenerate edges coinciding with the respective clipping boundaries. +// This is a sub-optimal solution, because that optimization would require +// extra, rather expensive math while the rasterizer tolerates it quite well, +// without any considerable overhead. +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_CLIP_POLYGON_INCLUDED +#define AGG_CONV_CLIP_POLYGON_INCLUDED + +#include "agg_basics.h" +#include "agg_conv_adaptor_vpgen.h" +#include "agg_vpgen_clip_polygon.h" + +namespace agg +{ + + //=======================================================conv_clip_polygon + template<class VertexSource> + struct conv_clip_polygon : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon> + { + typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon> base_type; + + conv_clip_polygon(VertexSource& vs) : + conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>(vs) {} + + void clip_box(double x1, double y1, double x2, double y2) + { + base_type::vpgen().clip_box(x1, y1, x2, y2); + } + + double x1() const { return base_type::vpgen().x1(); } + double y1() const { return base_type::vpgen().y1(); } + double x2() const { return base_type::vpgen().x2(); } + double y2() const { return base_type::vpgen().y2(); } + + private: + conv_clip_polygon(const conv_clip_polygon<VertexSource>&); + const conv_clip_polygon<VertexSource>& + operator = (const conv_clip_polygon<VertexSource>&); + }; + +} + +#endif diff --git a/include/agg_conv_clip_polyline.h b/include/agg_conv_clip_polyline.h new file mode 100644 index 0000000..f3fc288 --- /dev/null +++ b/include/agg_conv_clip_polyline.h @@ -0,0 +1,63 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// polyline clipping converter +// There an optimized Liang-Basky algorithm is used. +// The algorithm doesn't optimize the degenerate edges, i.e. it will never +// break a closed polyline into two or more ones, instead, there will be +// degenerate edges coinciding with the respective clipping boundaries. +// This is a sub-optimal solution, because that optimization would require +// extra, rather expensive math while the rasterizer tolerates it quite well, +// without any considerable overhead. +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_CLIP_polyline_INCLUDED +#define AGG_CONV_CLIP_polyline_INCLUDED + +#include "agg_basics.h" +#include "agg_conv_adaptor_vpgen.h" +#include "agg_vpgen_clip_polyline.h" + +namespace agg +{ + + //=======================================================conv_clip_polyline + template<class VertexSource> + struct conv_clip_polyline : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline> + { + typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline> base_type; + + conv_clip_polyline(VertexSource& vs) : + conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>(vs) {} + + void clip_box(double x1, double y1, double x2, double y2) + { + base_type::vpgen().clip_box(x1, y1, x2, y2); + } + + double x1() const { return base_type::vpgen().x1(); } + double y1() const { return base_type::vpgen().y1(); } + double x2() const { return base_type::vpgen().x2(); } + double y2() const { return base_type::vpgen().y2(); } + + private: + conv_clip_polyline(const conv_clip_polyline<VertexSource>&); + const conv_clip_polyline<VertexSource>& + operator = (const conv_clip_polyline<VertexSource>&); + }; + +} + +#endif diff --git a/include/agg_conv_close_polygon.h b/include/agg_conv_close_polygon.h new file mode 100644 index 0000000..c46594f --- /dev/null +++ b/include/agg_conv_close_polygon.h @@ -0,0 +1,125 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_CLOSE_POLYGON_INCLUDED +#define AGG_CONV_CLOSE_POLYGON_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //======================================================conv_close_polygon + template<class VertexSource> class conv_close_polygon + { + public: + explicit conv_close_polygon(VertexSource& vs) : m_source(&vs) {} + void attach(VertexSource& source) { m_source = &source; } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + conv_close_polygon(const conv_close_polygon<VertexSource>&); + const conv_close_polygon<VertexSource>& + operator = (const conv_close_polygon<VertexSource>&); + + VertexSource* m_source; + unsigned m_cmd[2]; + double m_x[2]; + double m_y[2]; + unsigned m_vertex; + bool m_line_to; + }; + + + + //------------------------------------------------------------------------ + template<class VertexSource> + void conv_close_polygon<VertexSource>::rewind(unsigned path_id) + { + m_source->rewind(path_id); + m_vertex = 2; + m_line_to = false; + } + + + + //------------------------------------------------------------------------ + template<class VertexSource> + unsigned conv_close_polygon<VertexSource>::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + for(;;) + { + if(m_vertex < 2) + { + *x = m_x[m_vertex]; + *y = m_y[m_vertex]; + cmd = m_cmd[m_vertex]; + ++m_vertex; + break; + } + + cmd = m_source->vertex(x, y); + + if(is_end_poly(cmd)) + { + cmd |= path_flags_close; + break; + } + + if(is_stop(cmd)) + { + if(m_line_to) + { + m_cmd[0] = path_cmd_end_poly | path_flags_close; + m_cmd[1] = path_cmd_stop; + m_vertex = 0; + m_line_to = false; + continue; + } + break; + } + + if(is_move_to(cmd)) + { + if(m_line_to) + { + m_x[0] = 0.0; + m_y[0] = 0.0; + m_cmd[0] = path_cmd_end_poly | path_flags_close; + m_x[1] = *x; + m_y[1] = *y; + m_cmd[1] = cmd; + m_vertex = 0; + m_line_to = false; + continue; + } + break; + } + + if(is_vertex(cmd)) + { + m_line_to = true; + break; + } + } + return cmd; + } + +} + +#endif diff --git a/include/agg_conv_concat.h b/include/agg_conv_concat.h new file mode 100644 index 0000000..745d349 --- /dev/null +++ b/include/agg_conv_concat.h @@ -0,0 +1,73 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_CONCAT_INCLUDED +#define AGG_CONV_CONCAT_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //=============================================================conv_concat + // Concatenation of two paths. Usually used to combine lines or curves + // with markers such as arrowheads + template<class VS1, class VS2> class conv_concat + { + public: + conv_concat(VS1& source1, VS2& source2) : + m_source1(&source1), m_source2(&source2), m_status(2) {} + void attach1(VS1& source) { m_source1 = &source; } + void attach2(VS2& source) { m_source2 = &source; } + + + void rewind(unsigned path_id) + { + m_source1->rewind(path_id); + m_source2->rewind(0); + m_status = 0; + } + + unsigned vertex(double* x, double* y) + { + unsigned cmd; + if(m_status == 0) + { + cmd = m_source1->vertex(x, y); + if(!is_stop(cmd)) return cmd; + m_status = 1; + } + if(m_status == 1) + { + cmd = m_source2->vertex(x, y); + if(!is_stop(cmd)) return cmd; + m_status = 2; + } + return path_cmd_stop; + } + + private: + conv_concat(const conv_concat<VS1, VS2>&); + const conv_concat<VS1, VS2>& + operator = (const conv_concat<VS1, VS2>&); + + VS1* m_source1; + VS2* m_source2; + int m_status; + + }; +} + + +#endif diff --git a/include/agg_conv_contour.h b/include/agg_conv_contour.h new file mode 100644 index 0000000..b4b5a90 --- /dev/null +++ b/include/agg_conv_contour.h @@ -0,0 +1,65 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// conv_stroke +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_CONTOUR_INCLUDED +#define AGG_CONV_CONTOUR_INCLUDED + +#include "agg_basics.h" +#include "agg_vcgen_contour.h" +#include "agg_conv_adaptor_vcgen.h" + +namespace agg +{ + + //-----------------------------------------------------------conv_contour + template<class VertexSource> + struct conv_contour : public conv_adaptor_vcgen<VertexSource, vcgen_contour> + { + typedef conv_adaptor_vcgen<VertexSource, vcgen_contour> base_type; + + conv_contour(VertexSource& vs) : + conv_adaptor_vcgen<VertexSource, vcgen_contour>(vs) + { + } + + void line_join(line_join_e lj) { base_type::generator().line_join(lj); } + void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); } + void width(double w) { base_type::generator().width(w); } + void miter_limit(double ml) { base_type::generator().miter_limit(ml); } + void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); } + void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); } + void approximation_scale(double as) { base_type::generator().approximation_scale(as); } + void auto_detect_orientation(bool v) { base_type::generator().auto_detect_orientation(v); } + + line_join_e line_join() const { return base_type::generator().line_join(); } + inner_join_e inner_join() const { return base_type::generator().inner_join(); } + double width() const { return base_type::generator().width(); } + double miter_limit() const { return base_type::generator().miter_limit(); } + double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); } + double approximation_scale() const { return base_type::generator().approximation_scale(); } + bool auto_detect_orientation() const { return base_type::generator().auto_detect_orientation(); } + + private: + conv_contour(const conv_contour<VertexSource>&); + const conv_contour<VertexSource>& + operator = (const conv_contour<VertexSource>&); + }; + +} + +#endif diff --git a/include/agg_conv_curve.h b/include/agg_conv_curve.h new file mode 100644 index 0000000..0be3b6f --- /dev/null +++ b/include/agg_conv_curve.h @@ -0,0 +1,201 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes conv_curve +// +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_CURVE_INCLUDED +#define AGG_CONV_CURVE_INCLUDED + +#include "agg_basics.h" +#include "agg_curves.h" + +namespace agg +{ + + + //---------------------------------------------------------------conv_curve + // Curve converter class. Any path storage can have Bezier curves defined + // by their control points. There're two types of curves supported: curve3 + // and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control + // point. Curve4 has 2 control points (4 points in total) and can be used + // to interpolate more complicated curves. Curve4, unlike curve3 can be used + // to approximate arcs, both circular and elliptical. Curves are approximated + // with straight lines and one of the approaches is just to store the whole + // sequence of vertices that approximate our curve. It takes additional + // memory, and at the same time the consecutive vertices can be calculated + // on demand. + // + // Initially, path storages are not suppose to keep all the vertices of the + // curves (although, nothing prevents us from doing so). Instead, path_storage + // keeps only vertices, needed to calculate a curve on demand. Those vertices + // are marked with special commands. So, if the path_storage contains curves + // (which are not real curves yet), and we render this storage directly, + // all we will see is only 2 or 3 straight line segments (for curve3 and + // curve4 respectively). If we need to see real curves drawn we need to + // include this class into the conversion pipeline. + // + // Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4 + // and converts these vertices into a move_to/line_to sequence. + //----------------------------------------------------------------------- + template<class VertexSource, + class Curve3=curve3, + class Curve4=curve4> class conv_curve + { + public: + typedef Curve3 curve3_type; + typedef Curve4 curve4_type; + typedef conv_curve<VertexSource, Curve3, Curve4> self_type; + + explicit conv_curve(VertexSource& source) : + m_source(&source), m_last_x(0.0), m_last_y(0.0) {} + void attach(VertexSource& source) { m_source = &source; } + + void approximation_method(curve_approximation_method_e v) + { + m_curve3.approximation_method(v); + m_curve4.approximation_method(v); + } + + curve_approximation_method_e approximation_method() const + { + return m_curve4.approximation_method(); + } + + void approximation_scale(double s) + { + m_curve3.approximation_scale(s); + m_curve4.approximation_scale(s); + } + + double approximation_scale() const + { + return m_curve4.approximation_scale(); + } + + void angle_tolerance(double v) + { + m_curve3.angle_tolerance(v); + m_curve4.angle_tolerance(v); + } + + double angle_tolerance() const + { + return m_curve4.angle_tolerance(); + } + + void cusp_limit(double v) + { + m_curve3.cusp_limit(v); + m_curve4.cusp_limit(v); + } + + double cusp_limit() const + { + return m_curve4.cusp_limit(); + } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + conv_curve(const self_type&); + const self_type& operator = (const self_type&); + + VertexSource* m_source; + double m_last_x; + double m_last_y; + curve3_type m_curve3; + curve4_type m_curve4; + }; + + + + //------------------------------------------------------------------------ + template<class VertexSource, class Curve3, class Curve4> + void conv_curve<VertexSource, Curve3, Curve4>::rewind(unsigned path_id) + { + m_source->rewind(path_id); + m_last_x = 0.0; + m_last_y = 0.0; + m_curve3.reset(); + m_curve4.reset(); + } + + + //------------------------------------------------------------------------ + template<class VertexSource, class Curve3, class Curve4> + unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y) + { + if(!is_stop(m_curve3.vertex(x, y))) + { + m_last_x = *x; + m_last_y = *y; + return path_cmd_line_to; + } + + if(!is_stop(m_curve4.vertex(x, y))) + { + m_last_x = *x; + m_last_y = *y; + return path_cmd_line_to; + } + + double ct2_x = 0; + double ct2_y = 0; + double end_x = 0; + double end_y = 0; + + unsigned cmd = m_source->vertex(x, y); + switch(cmd) + { + case path_cmd_curve3: + m_source->vertex(&end_x, &end_y); + + m_curve3.init(m_last_x, m_last_y, + *x, *y, + end_x, end_y); + + m_curve3.vertex(x, y); // First call returns path_cmd_move_to + m_curve3.vertex(x, y); // This is the first vertex of the curve + cmd = path_cmd_line_to; + break; + + case path_cmd_curve4: + m_source->vertex(&ct2_x, &ct2_y); + m_source->vertex(&end_x, &end_y); + + m_curve4.init(m_last_x, m_last_y, + *x, *y, + ct2_x, ct2_y, + end_x, end_y); + + m_curve4.vertex(x, y); // First call returns path_cmd_move_to + m_curve4.vertex(x, y); // This is the first vertex of the curve + cmd = path_cmd_line_to; + break; + } + m_last_x = *x; + m_last_y = *y; + return cmd; + } + + +} + + + +#endif diff --git a/include/agg_conv_dash.h b/include/agg_conv_dash.h new file mode 100644 index 0000000..23c13ad --- /dev/null +++ b/include/agg_conv_dash.h @@ -0,0 +1,68 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// conv_dash +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_DASH_INCLUDED +#define AGG_CONV_DASH_INCLUDED + +#include "agg_basics.h" +#include "agg_vcgen_dash.h" +#include "agg_conv_adaptor_vcgen.h" + +namespace agg +{ + + //---------------------------------------------------------------conv_dash + template<class VertexSource, class Markers=null_markers> + struct conv_dash : public conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers> + { + typedef Markers marker_type; + typedef conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers> base_type; + + conv_dash(VertexSource& vs) : + conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers>(vs) + { + } + + void remove_all_dashes() + { + base_type::generator().remove_all_dashes(); + } + + void add_dash(double dash_len, double gap_len) + { + base_type::generator().add_dash(dash_len, gap_len); + } + + void dash_start(double ds) + { + base_type::generator().dash_start(ds); + } + + void shorten(double s) { base_type::generator().shorten(s); } + double shorten() const { return base_type::generator().shorten(); } + + private: + conv_dash(const conv_dash<VertexSource, Markers>&); + const conv_dash<VertexSource, Markers>& + operator = (const conv_dash<VertexSource, Markers>&); + }; + + +} + +#endif diff --git a/include/agg_conv_gpc.h b/include/agg_conv_gpc.h new file mode 100644 index 0000000..6100179 --- /dev/null +++ b/include/agg_conv_gpc.h @@ -0,0 +1,432 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// General Polygon Clipper based on the GPC library by Alan Murta +// Union, Intersection, XOR, A-B, B-A +// Contact the author if you intend to use it in commercial applications! +// http://www.cs.man.ac.uk/aig/staff/alan/software/ +// Alan Murta (email: gpc@cs.man.ac.uk) +// +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_GPC_INCLUDED +#define AGG_CONV_GPC_INCLUDED + +#include <cstring> +#include "agg_basics.h" +#include "agg_array.h" + +extern "C" +{ +#include "gpc.h" +} + +namespace agg +{ + enum gpc_op_e + { + gpc_or, + gpc_and, + gpc_xor, + gpc_a_minus_b, + gpc_b_minus_a + }; + + + //================================================================conv_gpc + template<class VSA, class VSB> class conv_gpc + { + enum status + { + status_move_to, + status_line_to, + status_stop + }; + + struct contour_header_type + { + int num_vertices; + int hole_flag; + gpc_vertex* vertices; + }; + + typedef pod_bvector<gpc_vertex, 8> vertex_array_type; + typedef pod_bvector<contour_header_type, 6> contour_header_array_type; + + + public: + typedef VSA source_a_type; + typedef VSB source_b_type; + typedef conv_gpc<source_a_type, source_b_type> self_type; + + ~conv_gpc() + { + free_gpc_data(); + } + + conv_gpc(source_a_type& a, source_b_type& b, gpc_op_e op = gpc_or) : + m_src_a(&a), + m_src_b(&b), + m_status(status_move_to), + m_vertex(-1), + m_contour(-1), + m_operation(op) + { + std::memset(&m_poly_a, 0, sizeof(m_poly_a)); + std::memset(&m_poly_b, 0, sizeof(m_poly_b)); + std::memset(&m_result, 0, sizeof(m_result)); + } + + void attach1(VSA& source) { m_src_a = &source; } + void attach2(VSB& source) { m_src_b = &source; } + + void operation(gpc_op_e v) { m_operation = v; } + + // Vertex Source Interface + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + conv_gpc(const conv_gpc<VSA, VSB>&); + const conv_gpc<VSA, VSB>& operator = (const conv_gpc<VSA, VSB>&); + + //-------------------------------------------------------------------- + void free_polygon(gpc_polygon& p); + void free_result(); + void free_gpc_data(); + void start_contour(); + void add_vertex(double x, double y); + void end_contour(unsigned orientation); + void make_polygon(gpc_polygon& p); + void start_extracting(); + bool next_contour(); + bool next_vertex(double* x, double* y); + + + //-------------------------------------------------------------------- + template<class VS> void add(VS& src, gpc_polygon& p) + { + unsigned cmd; + double x, y; + double start_x = 0.0; + double start_y = 0.0; + bool line_to = false; + unsigned orientation = 0; + + m_contour_accumulator.remove_all(); + + while(!is_stop(cmd = src.vertex(&x, &y))) + { + if(is_vertex(cmd)) + { + if(is_move_to(cmd)) + { + if(line_to) + { + end_contour(orientation); + orientation = 0; + } + start_contour(); + start_x = x; + start_y = y; + } + add_vertex(x, y); + line_to = true; + } + else + { + if(is_end_poly(cmd)) + { + orientation = get_orientation(cmd); + if(line_to && is_closed(cmd)) + { + add_vertex(start_x, start_y); + } + } + } + } + if(line_to) + { + end_contour(orientation); + } + make_polygon(p); + } + + + private: + //-------------------------------------------------------------------- + source_a_type* m_src_a; + source_b_type* m_src_b; + status m_status; + int m_vertex; + int m_contour; + gpc_op_e m_operation; + vertex_array_type m_vertex_accumulator; + contour_header_array_type m_contour_accumulator; + gpc_polygon m_poly_a; + gpc_polygon m_poly_b; + gpc_polygon m_result; + }; + + + + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + void conv_gpc<VSA, VSB>::free_polygon(gpc_polygon& p) + { + int i; + for(i = 0; i < p.num_contours; i++) + { + pod_allocator<gpc_vertex>::deallocate(p.contour[i].vertex, + p.contour[i].num_vertices); + } + pod_allocator<gpc_vertex_list>::deallocate(p.contour, p.num_contours); + std::memset(&p, 0, sizeof(gpc_polygon)); + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + void conv_gpc<VSA, VSB>::free_result() + { + if(m_result.contour) + { + gpc_free_polygon(&m_result); + } + std::memset(&m_result, 0, sizeof(m_result)); + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + void conv_gpc<VSA, VSB>::free_gpc_data() + { + free_polygon(m_poly_a); + free_polygon(m_poly_b); + free_result(); + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + void conv_gpc<VSA, VSB>::start_contour() + { + contour_header_type h; + std::memset(&h, 0, sizeof(h)); + m_contour_accumulator.add(h); + m_vertex_accumulator.remove_all(); + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + inline void conv_gpc<VSA, VSB>::add_vertex(double x, double y) + { + gpc_vertex v; + v.x = x; + v.y = y; + m_vertex_accumulator.add(v); + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + void conv_gpc<VSA, VSB>::end_contour(unsigned /*orientation*/) + { + if(m_contour_accumulator.size()) + { + if(m_vertex_accumulator.size() > 2) + { + contour_header_type& h = + m_contour_accumulator[m_contour_accumulator.size() - 1]; + + h.num_vertices = m_vertex_accumulator.size(); + h.hole_flag = 0; + + // TO DO: Clarify the "holes" + //if(is_cw(orientation)) h.hole_flag = 1; + + h.vertices = pod_allocator<gpc_vertex>::allocate(h.num_vertices); + gpc_vertex* d = h.vertices; + int i; + for(i = 0; i < h.num_vertices; i++) + { + const gpc_vertex& s = m_vertex_accumulator[i]; + d->x = s.x; + d->y = s.y; + ++d; + } + } + else + { + m_vertex_accumulator.remove_last(); + } + } + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + void conv_gpc<VSA, VSB>::make_polygon(gpc_polygon& p) + { + free_polygon(p); + if(m_contour_accumulator.size()) + { + p.num_contours = m_contour_accumulator.size(); + + p.hole = 0; + p.contour = pod_allocator<gpc_vertex_list>::allocate(p.num_contours); + + int i; + gpc_vertex_list* pv = p.contour; + for(i = 0; i < p.num_contours; i++) + { + const contour_header_type& h = m_contour_accumulator[i]; + pv->num_vertices = h.num_vertices; + pv->vertex = h.vertices; + ++pv; + } + } + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + void conv_gpc<VSA, VSB>::start_extracting() + { + m_status = status_move_to; + m_contour = -1; + m_vertex = -1; + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + bool conv_gpc<VSA, VSB>::next_contour() + { + if(++m_contour < m_result.num_contours) + { + m_vertex = -1; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + inline bool conv_gpc<VSA, VSB>::next_vertex(double* x, double* y) + { + const gpc_vertex_list& vlist = m_result.contour[m_contour]; + if(++m_vertex < vlist.num_vertices) + { + const gpc_vertex& v = vlist.vertex[m_vertex]; + *x = v.x; + *y = v.y; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + void conv_gpc<VSA, VSB>::rewind(unsigned path_id) + { + free_result(); + m_src_a->rewind(path_id); + m_src_b->rewind(path_id); + add(*m_src_a, m_poly_a); + add(*m_src_b, m_poly_b); + switch(m_operation) + { + case gpc_or: + gpc_polygon_clip(GPC_UNION, + &m_poly_a, + &m_poly_b, + &m_result); + break; + + case gpc_and: + gpc_polygon_clip(GPC_INT, + &m_poly_a, + &m_poly_b, + &m_result); + break; + + case gpc_xor: + gpc_polygon_clip(GPC_XOR, + &m_poly_a, + &m_poly_b, + &m_result); + break; + + case gpc_a_minus_b: + gpc_polygon_clip(GPC_DIFF, + &m_poly_a, + &m_poly_b, + &m_result); + break; + + case gpc_b_minus_a: + gpc_polygon_clip(GPC_DIFF, + &m_poly_b, + &m_poly_a, + &m_result); + break; + } + start_extracting(); + } + + + //------------------------------------------------------------------------ + template<class VSA, class VSB> + unsigned conv_gpc<VSA, VSB>::vertex(double* x, double* y) + { + if(m_status == status_move_to) + { + if(next_contour()) + { + if(next_vertex(x, y)) + { + m_status = status_line_to; + return path_cmd_move_to; + } + m_status = status_stop; + return path_cmd_end_poly | path_flags_close; + } + } + else + { + if(next_vertex(x, y)) + { + return path_cmd_line_to; + } + else + { + m_status = status_move_to; + } + return path_cmd_end_poly | path_flags_close; + } + return path_cmd_stop; + } + + +} + + +#endif diff --git a/include/agg_conv_marker.h b/include/agg_conv_marker.h new file mode 100644 index 0000000..0df56e3 --- /dev/null +++ b/include/agg_conv_marker.h @@ -0,0 +1,149 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// conv_marker +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_MARKER_INCLUDED +#define AGG_CONV_MARKER_INCLUDED + +#include <cmath> +#include "agg_basics.h" +#include "agg_trans_affine.h" + +namespace agg +{ + //-------------------------------------------------------------conv_marker + template<class MarkerLocator, class MarkerShapes> + class conv_marker + { + public: + conv_marker(MarkerLocator& ml, MarkerShapes& ms); + + trans_affine& transform() { return m_transform; } + const trans_affine& transform() const { return m_transform; } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + conv_marker(const conv_marker<MarkerLocator, MarkerShapes>&); + const conv_marker<MarkerLocator, MarkerShapes>& + operator = (const conv_marker<MarkerLocator, MarkerShapes>&); + + enum status_e + { + initial, + markers, + polygon, + stop + }; + + MarkerLocator* m_marker_locator; + MarkerShapes* m_marker_shapes; + trans_affine m_transform; + trans_affine m_mtx; + status_e m_status; + unsigned m_marker; + unsigned m_num_markers; + }; + + + //------------------------------------------------------------------------ + template<class MarkerLocator, class MarkerShapes> + conv_marker<MarkerLocator, MarkerShapes>::conv_marker(MarkerLocator& ml, MarkerShapes& ms) : + m_marker_locator(&ml), + m_marker_shapes(&ms), + m_status(initial), + m_marker(0), + m_num_markers(1) + { + } + + + //------------------------------------------------------------------------ + template<class MarkerLocator, class MarkerShapes> + void conv_marker<MarkerLocator, MarkerShapes>::rewind(unsigned) + { + m_status = initial; + m_marker = 0; + m_num_markers = 1; + } + + + //------------------------------------------------------------------------ + template<class MarkerLocator, class MarkerShapes> + unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_move_to; + double x1, y1, x2, y2; + + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + if(m_num_markers == 0) + { + cmd = path_cmd_stop; + break; + } + m_marker_locator->rewind(m_marker); + ++m_marker; + m_num_markers = 0; + m_status = markers; + + case markers: + if(is_stop(m_marker_locator->vertex(&x1, &y1))) + { + m_status = initial; + break; + } + if(is_stop(m_marker_locator->vertex(&x2, &y2))) + { + m_status = initial; + break; + } + ++m_num_markers; + m_mtx = m_transform; + m_mtx *= trans_affine_rotation(std::atan2(y2 - y1, x2 - x1)); + m_mtx *= trans_affine_translation(x1, y1); + m_marker_shapes->rewind(m_marker - 1); + m_status = polygon; + + case polygon: + cmd = m_marker_shapes->vertex(x, y); + if(is_stop(cmd)) + { + cmd = path_cmd_move_to; + m_status = markers; + break; + } + m_mtx.transform(x, y); + return cmd; + + case stop: + cmd = path_cmd_stop; + break; + } + } + return cmd; + } + +} + + +#endif + diff --git a/include/agg_conv_marker_adaptor.h b/include/agg_conv_marker_adaptor.h new file mode 100644 index 0000000..4486d6a --- /dev/null +++ b/include/agg_conv_marker_adaptor.h @@ -0,0 +1,51 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_MARKER_ADAPTOR_INCLUDED +#define AGG_CONV_MARKER_ADAPTOR_INCLUDED + +#include "agg_basics.h" +#include "agg_conv_adaptor_vcgen.h" +#include "agg_vcgen_vertex_sequence.h" + +namespace agg +{ + + //=====================================================conv_marker_adaptor + template<class VertexSource, class Markers=null_markers> + struct conv_marker_adaptor : + public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers> + { + typedef Markers marker_type; + typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers> base_type; + + conv_marker_adaptor(VertexSource& vs) : + conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>(vs) + { + } + + void shorten(double s) { base_type::generator().shorten(s); } + double shorten() const { return base_type::generator().shorten(); } + + private: + conv_marker_adaptor(const conv_marker_adaptor<VertexSource, Markers>&); + const conv_marker_adaptor<VertexSource, Markers>& + operator = (const conv_marker_adaptor<VertexSource, Markers>&); + }; + + +} + +#endif diff --git a/include/agg_conv_segmentator.h b/include/agg_conv_segmentator.h new file mode 100644 index 0000000..e69a9e7 --- /dev/null +++ b/include/agg_conv_segmentator.h @@ -0,0 +1,48 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_SEGMENTATOR_INCLUDED +#define AGG_CONV_SEGMENTATOR_INCLUDED + +#include "agg_basics.h" +#include "agg_conv_adaptor_vpgen.h" +#include "agg_vpgen_segmentator.h" + +namespace agg +{ + + //========================================================conv_segmentator + template<class VertexSource> + struct conv_segmentator : public conv_adaptor_vpgen<VertexSource, vpgen_segmentator> + { + typedef conv_adaptor_vpgen<VertexSource, vpgen_segmentator> base_type; + + conv_segmentator(VertexSource& vs) : + conv_adaptor_vpgen<VertexSource, vpgen_segmentator>(vs) {} + + void approximation_scale(double s) { base_type::vpgen().approximation_scale(s); } + double approximation_scale() const { return base_type::vpgen().approximation_scale(); } + + private: + conv_segmentator(const conv_segmentator<VertexSource>&); + const conv_segmentator<VertexSource>& + operator = (const conv_segmentator<VertexSource>&); + }; + + +} + +#endif + diff --git a/include/agg_conv_shorten_path.h b/include/agg_conv_shorten_path.h new file mode 100644 index 0000000..5617e51 --- /dev/null +++ b/include/agg_conv_shorten_path.h @@ -0,0 +1,50 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_SHORTEN_PATH_INCLUDED +#define AGG_CONV_SHORTEN_PATH_INCLUDED + +#include "agg_basics.h" +#include "agg_conv_adaptor_vcgen.h" +#include "agg_vcgen_vertex_sequence.h" + +namespace agg +{ + + //=======================================================conv_shorten_path + template<class VertexSource> class conv_shorten_path : + public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence> + { + public: + typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence> base_type; + + conv_shorten_path(VertexSource& vs) : + conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>(vs) + { + } + + void shorten(double s) { base_type::generator().shorten(s); } + double shorten() const { return base_type::generator().shorten(); } + + private: + conv_shorten_path(const conv_shorten_path<VertexSource>&); + const conv_shorten_path<VertexSource>& + operator = (const conv_shorten_path<VertexSource>&); + }; + + +} + +#endif diff --git a/include/agg_conv_smooth_poly1.h b/include/agg_conv_smooth_poly1.h new file mode 100644 index 0000000..4ac4e3d --- /dev/null +++ b/include/agg_conv_smooth_poly1.h @@ -0,0 +1,80 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Smooth polygon generator +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_SMOOTH_POLY1_INCLUDED +#define AGG_CONV_SMOOTH_POLY1_INCLUDED + +#include "agg_basics.h" +#include "agg_vcgen_smooth_poly1.h" +#include "agg_conv_adaptor_vcgen.h" +#include "agg_conv_curve.h" + + +namespace agg +{ + + //-------------------------------------------------------conv_smooth_poly1 + template<class VertexSource> + struct conv_smooth_poly1 : + public conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1> + { + typedef conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1> base_type; + + conv_smooth_poly1(VertexSource& vs) : + conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1>(vs) + { + } + + void smooth_value(double v) { base_type::generator().smooth_value(v); } + double smooth_value() const { return base_type::generator().smooth_value(); } + + private: + conv_smooth_poly1(const conv_smooth_poly1<VertexSource>&); + const conv_smooth_poly1<VertexSource>& + operator = (const conv_smooth_poly1<VertexSource>&); + }; + + + + //-------------------------------------------------conv_smooth_poly1_curve + template<class VertexSource> + struct conv_smooth_poly1_curve : + public conv_curve<conv_smooth_poly1<VertexSource> > + { + conv_smooth_poly1_curve(VertexSource& vs) : + conv_curve<conv_smooth_poly1<VertexSource> >(m_smooth), + m_smooth(vs) + { + } + + void smooth_value(double v) { m_smooth.generator().smooth_value(v); } + double smooth_value() const { return m_smooth.generator().smooth_value(); } + + private: + conv_smooth_poly1_curve(const conv_smooth_poly1_curve<VertexSource>&); + const conv_smooth_poly1_curve<VertexSource>& + operator = (const conv_smooth_poly1_curve<VertexSource>&); + + conv_smooth_poly1<VertexSource> m_smooth; + }; + +} + + +#endif + diff --git a/include/agg_conv_stroke.h b/include/agg_conv_stroke.h new file mode 100644 index 0000000..e19a6b6 --- /dev/null +++ b/include/agg_conv_stroke.h @@ -0,0 +1,73 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// conv_stroke +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_STROKE_INCLUDED +#define AGG_CONV_STROKE_INCLUDED + +#include "agg_basics.h" +#include "agg_vcgen_stroke.h" +#include "agg_conv_adaptor_vcgen.h" + +namespace agg +{ + + //-------------------------------------------------------------conv_stroke + template<class VertexSource, class Markers=null_markers> + struct conv_stroke : + public conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers> + { + typedef Markers marker_type; + typedef conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers> base_type; + + conv_stroke(VertexSource& vs) : + conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>(vs) + { + } + + void line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); } + void line_join(line_join_e lj) { base_type::generator().line_join(lj); } + void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); } + + line_cap_e line_cap() const { return base_type::generator().line_cap(); } + line_join_e line_join() const { return base_type::generator().line_join(); } + inner_join_e inner_join() const { return base_type::generator().inner_join(); } + + void width(double w) { base_type::generator().width(w); } + void miter_limit(double ml) { base_type::generator().miter_limit(ml); } + void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); } + void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); } + void approximation_scale(double as) { base_type::generator().approximation_scale(as); } + + double width() const { return base_type::generator().width(); } + double miter_limit() const { return base_type::generator().miter_limit(); } + double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); } + double approximation_scale() const { return base_type::generator().approximation_scale(); } + + void shorten(double s) { base_type::generator().shorten(s); } + double shorten() const { return base_type::generator().shorten(); } + + private: + conv_stroke(const conv_stroke<VertexSource, Markers>&); + const conv_stroke<VertexSource, Markers>& + operator = (const conv_stroke<VertexSource, Markers>&); + + }; + +} + +#endif diff --git a/include/agg_conv_transform.h b/include/agg_conv_transform.h new file mode 100644 index 0000000..0c88a24 --- /dev/null +++ b/include/agg_conv_transform.h @@ -0,0 +1,68 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class conv_transform +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_TRANSFORM_INCLUDED +#define AGG_CONV_TRANSFORM_INCLUDED + +#include "agg_basics.h" +#include "agg_trans_affine.h" + +namespace agg +{ + + //----------------------------------------------------------conv_transform + template<class VertexSource, class Transformer=trans_affine> class conv_transform + { + public: + conv_transform(VertexSource& source, Transformer& tr) : + m_source(&source), m_trans(&tr) {} + void attach(VertexSource& source) { m_source = &source; } + + void rewind(unsigned path_id) + { + m_source->rewind(path_id); + } + + unsigned vertex(double* x, double* y) + { + unsigned cmd = m_source->vertex(x, y); + if(is_vertex(cmd)) + { + m_trans->transform(x, y); + } + return cmd; + } + + void transformer(Transformer& tr) + { + m_trans = &tr; + } + + private: + conv_transform(const conv_transform<VertexSource>&); + const conv_transform<VertexSource>& + operator = (const conv_transform<VertexSource>&); + + VertexSource* m_source; + Transformer* m_trans; + }; + + +} + +#endif diff --git a/include/agg_conv_unclose_polygon.h b/include/agg_conv_unclose_polygon.h new file mode 100644 index 0000000..fe5c263 --- /dev/null +++ b/include/agg_conv_unclose_polygon.h @@ -0,0 +1,52 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_UNCLOSE_POLYGON_INCLUDED +#define AGG_CONV_UNCLOSE_POLYGON_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //====================================================conv_unclose_polygon + template<class VertexSource> class conv_unclose_polygon + { + public: + explicit conv_unclose_polygon(VertexSource& vs) : m_source(&vs) {} + void attach(VertexSource& source) { m_source = &source; } + + void rewind(unsigned path_id) + { + m_source->rewind(path_id); + } + + unsigned vertex(double* x, double* y) + { + unsigned cmd = m_source->vertex(x, y); + if(is_end_poly(cmd)) cmd &= ~path_flags_close; + return cmd; + } + + private: + conv_unclose_polygon(const conv_unclose_polygon<VertexSource>&); + const conv_unclose_polygon<VertexSource>& + operator = (const conv_unclose_polygon<VertexSource>&); + + VertexSource* m_source; + }; + +} + +#endif diff --git a/include/agg_curves.h b/include/agg_curves.h new file mode 100644 index 0000000..63a4813 --- /dev/null +++ b/include/agg_curves.h @@ -0,0 +1,695 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// Copyright (C) 2005 Tony Juricic (tonygeek@yahoo.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 +//---------------------------------------------------------------------------- + +#ifndef AGG_CURVES_INCLUDED +#define AGG_CURVES_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + + // See Implementation agg_curves.cpp + + //--------------------------------------------curve_approximation_method_e + enum curve_approximation_method_e + { + curve_inc, + curve_div + }; + + //--------------------------------------------------------------curve3_inc + class curve3_inc + { + public: + curve3_inc() : + m_num_steps(0), m_step(0), m_scale(1.0) { } + + curve3_inc(double x1, double y1, + double x2, double y2, + double x3, double y3) : + m_num_steps(0), m_step(0), m_scale(1.0) + { + init(x1, y1, x2, y2, x3, y3); + } + + void reset() { m_num_steps = 0; m_step = -1; } + void init(double x1, double y1, + double x2, double y2, + double x3, double y3); + + void approximation_method(curve_approximation_method_e) {} + curve_approximation_method_e approximation_method() const { return curve_inc; } + + void approximation_scale(double s); + double approximation_scale() const; + + void angle_tolerance(double) {} + double angle_tolerance() const { return 0.0; } + + void cusp_limit(double) {} + double cusp_limit() const { return 0.0; } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + int m_num_steps; + int m_step; + double m_scale; + double m_start_x; + double m_start_y; + double m_end_x; + double m_end_y; + double m_fx; + double m_fy; + double m_dfx; + double m_dfy; + double m_ddfx; + double m_ddfy; + double m_saved_fx; + double m_saved_fy; + double m_saved_dfx; + double m_saved_dfy; + }; + + + + + + //-------------------------------------------------------------curve3_div + class curve3_div + { + public: + curve3_div() : + m_approximation_scale(1.0), + m_distance_tolerance_square(0.0), + m_angle_tolerance(0.0), + m_count(0) + {} + + curve3_div(double x1, double y1, + double x2, double y2, + double x3, double y3) : + m_approximation_scale(1.0), + m_angle_tolerance(0.0), + m_count(0) + { + init(x1, y1, x2, y2, x3, y3); + } + + void reset() { m_points.remove_all(); m_count = 0; } + void init(double x1, double y1, + double x2, double y2, + double x3, double y3); + + void approximation_method(curve_approximation_method_e) {} + curve_approximation_method_e approximation_method() const { return curve_div; } + + void approximation_scale(double s) { m_approximation_scale = s; } + double approximation_scale() const { return m_approximation_scale; } + + void angle_tolerance(double a) { m_angle_tolerance = a; } + double angle_tolerance() const { return m_angle_tolerance; } + + void cusp_limit(double) {} + double cusp_limit() const { return 0.0; } + + void rewind(unsigned) + { + m_count = 0; + } + + unsigned vertex(double* x, double* y) + { + if(m_count >= m_points.size()) return path_cmd_stop; + const point_d& p = m_points[m_count++]; + *x = p.x; + *y = p.y; + return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to; + } + + private: + void bezier(double x1, double y1, + double x2, double y2, + double x3, double y3); + void recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + unsigned level); + + double m_approximation_scale; + double m_distance_tolerance_square; + double m_angle_tolerance; + unsigned m_count; + pod_bvector<point_d> m_points; + }; + + + + + + + + //-------------------------------------------------------------curve4_points + struct curve4_points + { + double cp[8]; + curve4_points() {} + curve4_points(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2; + cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4; + } + void init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2; + cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4; + } + double operator [] (unsigned i) const { return cp[i]; } + double& operator [] (unsigned i) { return cp[i]; } + }; + + + + //-------------------------------------------------------------curve4_inc + class curve4_inc + { + public: + curve4_inc() : + m_num_steps(0), m_step(0), m_scale(1.0) { } + + curve4_inc(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) : + m_num_steps(0), m_step(0), m_scale(1.0) + { + init(x1, y1, x2, y2, x3, y3, x4, y4); + } + + curve4_inc(const curve4_points& cp) : + m_num_steps(0), m_step(0), m_scale(1.0) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void reset() { m_num_steps = 0; m_step = -1; } + void init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4); + + void init(const curve4_points& cp) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void approximation_method(curve_approximation_method_e) {} + curve_approximation_method_e approximation_method() const { return curve_inc; } + + void approximation_scale(double s); + double approximation_scale() const; + + void angle_tolerance(double) {} + double angle_tolerance() const { return 0.0; } + + void cusp_limit(double) {} + double cusp_limit() const { return 0.0; } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + int m_num_steps; + int m_step; + double m_scale; + double m_start_x; + double m_start_y; + double m_end_x; + double m_end_y; + double m_fx; + double m_fy; + double m_dfx; + double m_dfy; + double m_ddfx; + double m_ddfy; + double m_dddfx; + double m_dddfy; + double m_saved_fx; + double m_saved_fy; + double m_saved_dfx; + double m_saved_dfy; + double m_saved_ddfx; + double m_saved_ddfy; + }; + + + + //-------------------------------------------------------catrom_to_bezier + inline curve4_points catrom_to_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + // Trans. matrix Catmull-Rom to Bezier + // + // 0 1 0 0 + // -1/6 1 1/6 0 + // 0 1/6 1 -1/6 + // 0 0 1 0 + // + return curve4_points( + x2, + y2, + (-x1 + 6*x2 + x3) / 6, + (-y1 + 6*y2 + y3) / 6, + ( x2 + 6*x3 - x4) / 6, + ( y2 + 6*y3 - y4) / 6, + x3, + y3); + } + + + //----------------------------------------------------------------------- + inline curve4_points + catrom_to_bezier(const curve4_points& cp) + { + return catrom_to_bezier(cp[0], cp[1], cp[2], cp[3], + cp[4], cp[5], cp[6], cp[7]); + } + + + + //-----------------------------------------------------ubspline_to_bezier + inline curve4_points ubspline_to_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + // Trans. matrix Uniform BSpline to Bezier + // + // 1/6 4/6 1/6 0 + // 0 4/6 2/6 0 + // 0 2/6 4/6 0 + // 0 1/6 4/6 1/6 + // + return curve4_points( + (x1 + 4*x2 + x3) / 6, + (y1 + 4*y2 + y3) / 6, + (4*x2 + 2*x3) / 6, + (4*y2 + 2*y3) / 6, + (2*x2 + 4*x3) / 6, + (2*y2 + 4*y3) / 6, + (x2 + 4*x3 + x4) / 6, + (y2 + 4*y3 + y4) / 6); + } + + + //----------------------------------------------------------------------- + inline curve4_points + ubspline_to_bezier(const curve4_points& cp) + { + return ubspline_to_bezier(cp[0], cp[1], cp[2], cp[3], + cp[4], cp[5], cp[6], cp[7]); + } + + + + + //------------------------------------------------------hermite_to_bezier + inline curve4_points hermite_to_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + // Trans. matrix Hermite to Bezier + // + // 1 0 0 0 + // 1 0 1/3 0 + // 0 1 0 -1/3 + // 0 1 0 0 + // + return curve4_points( + x1, + y1, + (3*x1 + x3) / 3, + (3*y1 + y3) / 3, + (3*x2 - x4) / 3, + (3*y2 - y4) / 3, + x2, + y2); + } + + + + //----------------------------------------------------------------------- + inline curve4_points + hermite_to_bezier(const curve4_points& cp) + { + return hermite_to_bezier(cp[0], cp[1], cp[2], cp[3], + cp[4], cp[5], cp[6], cp[7]); + } + + + //-------------------------------------------------------------curve4_div + class curve4_div + { + public: + curve4_div() : + m_approximation_scale(1.0), + m_distance_tolerance_square(0.0), + m_angle_tolerance(0.0), + m_cusp_limit(0.0), + m_count(0) + {} + + curve4_div(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) : + m_approximation_scale(1.0), + m_angle_tolerance(0.0), + m_cusp_limit(0.0), + m_count(0) + { + init(x1, y1, x2, y2, x3, y3, x4, y4); + } + + curve4_div(const curve4_points& cp) : + m_approximation_scale(1.0), + m_angle_tolerance(0.0), + m_count(0) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void reset() { m_points.remove_all(); m_count = 0; } + void init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4); + + void init(const curve4_points& cp) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void approximation_method(curve_approximation_method_e) {} + + curve_approximation_method_e approximation_method() const + { + return curve_div; + } + + void approximation_scale(double s) { m_approximation_scale = s; } + double approximation_scale() const { return m_approximation_scale; } + + void angle_tolerance(double a) { m_angle_tolerance = a; } + double angle_tolerance() const { return m_angle_tolerance; } + + void cusp_limit(double v) + { + m_cusp_limit = (v == 0.0) ? 0.0 : pi - v; + } + + double cusp_limit() const + { + return (m_cusp_limit == 0.0) ? 0.0 : pi - m_cusp_limit; + } + + void rewind(unsigned) + { + m_count = 0; + } + + unsigned vertex(double* x, double* y) + { + if(m_count >= m_points.size()) return path_cmd_stop; + const point_d& p = m_points[m_count++]; + *x = p.x; + *y = p.y; + return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to; + } + + private: + void bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4); + + void recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4, + unsigned level); + + double m_approximation_scale; + double m_distance_tolerance_square; + double m_angle_tolerance; + double m_cusp_limit; + unsigned m_count; + pod_bvector<point_d> m_points; + }; + + + //-----------------------------------------------------------------curve3 + class curve3 + { + public: + curve3() : m_approximation_method(curve_div) {} + curve3(double x1, double y1, + double x2, double y2, + double x3, double y3) : + m_approximation_method(curve_div) + { + init(x1, y1, x2, y2, x3, y3); + } + + void reset() + { + m_curve_inc.reset(); + m_curve_div.reset(); + } + + void init(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + if(m_approximation_method == curve_inc) + { + m_curve_inc.init(x1, y1, x2, y2, x3, y3); + } + else + { + m_curve_div.init(x1, y1, x2, y2, x3, y3); + } + } + + void approximation_method(curve_approximation_method_e v) + { + m_approximation_method = v; + } + + curve_approximation_method_e approximation_method() const + { + return m_approximation_method; + } + + void approximation_scale(double s) + { + m_curve_inc.approximation_scale(s); + m_curve_div.approximation_scale(s); + } + + double approximation_scale() const + { + return m_curve_inc.approximation_scale(); + } + + void angle_tolerance(double a) + { + m_curve_div.angle_tolerance(a); + } + + double angle_tolerance() const + { + return m_curve_div.angle_tolerance(); + } + + void cusp_limit(double v) + { + m_curve_div.cusp_limit(v); + } + + double cusp_limit() const + { + return m_curve_div.cusp_limit(); + } + + void rewind(unsigned path_id) + { + if(m_approximation_method == curve_inc) + { + m_curve_inc.rewind(path_id); + } + else + { + m_curve_div.rewind(path_id); + } + } + + unsigned vertex(double* x, double* y) + { + if(m_approximation_method == curve_inc) + { + return m_curve_inc.vertex(x, y); + } + return m_curve_div.vertex(x, y); + } + + private: + curve3_inc m_curve_inc; + curve3_div m_curve_div; + curve_approximation_method_e m_approximation_method; + }; + + + + + + //-----------------------------------------------------------------curve4 + class curve4 + { + public: + curve4() : m_approximation_method(curve_div) {} + curve4(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) : + m_approximation_method(curve_div) + { + init(x1, y1, x2, y2, x3, y3, x4, y4); + } + + curve4(const curve4_points& cp) : + m_approximation_method(curve_div) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void reset() + { + m_curve_inc.reset(); + m_curve_div.reset(); + } + + void init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + if(m_approximation_method == curve_inc) + { + m_curve_inc.init(x1, y1, x2, y2, x3, y3, x4, y4); + } + else + { + m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4); + } + } + + void init(const curve4_points& cp) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void approximation_method(curve_approximation_method_e v) + { + m_approximation_method = v; + } + + curve_approximation_method_e approximation_method() const + { + return m_approximation_method; + } + + void approximation_scale(double s) + { + m_curve_inc.approximation_scale(s); + m_curve_div.approximation_scale(s); + } + double approximation_scale() const { return m_curve_inc.approximation_scale(); } + + void angle_tolerance(double v) + { + m_curve_div.angle_tolerance(v); + } + + double angle_tolerance() const + { + return m_curve_div.angle_tolerance(); + } + + void cusp_limit(double v) + { + m_curve_div.cusp_limit(v); + } + + double cusp_limit() const + { + return m_curve_div.cusp_limit(); + } + + void rewind(unsigned path_id) + { + if(m_approximation_method == curve_inc) + { + m_curve_inc.rewind(path_id); + } + else + { + m_curve_div.rewind(path_id); + } + } + + unsigned vertex(double* x, double* y) + { + if(m_approximation_method == curve_inc) + { + return m_curve_inc.vertex(x, y); + } + return m_curve_div.vertex(x, y); + } + + private: + curve4_inc m_curve_inc; + curve4_div m_curve_div; + curve_approximation_method_e m_approximation_method; + }; + + + + +} + +#endif diff --git a/include/agg_dda_line.h b/include/agg_dda_line.h new file mode 100644 index 0000000..c535816 --- /dev/null +++ b/include/agg_dda_line.h @@ -0,0 +1,290 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes dda_line_interpolator, dda2_line_interpolator +// +//---------------------------------------------------------------------------- + +#ifndef AGG_DDA_LINE_INCLUDED +#define AGG_DDA_LINE_INCLUDED + +#include <cstdlib> +#include "agg_basics.h" + +namespace agg +{ + + //===================================================dda_line_interpolator + template<int FractionShift, int YShift=0> class dda_line_interpolator + { + public: + //-------------------------------------------------------------------- + dda_line_interpolator() {} + + //-------------------------------------------------------------------- + dda_line_interpolator(int y1, int y2, unsigned count) : + m_y(y1), + m_inc(((y2 - y1) << FractionShift) / int(count)), + m_dy(0) + { + } + + //-------------------------------------------------------------------- + void operator ++ () + { + m_dy += m_inc; + } + + //-------------------------------------------------------------------- + void operator -- () + { + m_dy -= m_inc; + } + + //-------------------------------------------------------------------- + void operator += (unsigned n) + { + m_dy += m_inc * n; + } + + //-------------------------------------------------------------------- + void operator -= (unsigned n) + { + m_dy -= m_inc * n; + } + + + //-------------------------------------------------------------------- + int y() const { return m_y + (m_dy >> (FractionShift-YShift)); } + int dy() const { return m_dy; } + + + private: + int m_y; + int m_inc; + int m_dy; + }; + + + + + + //=================================================dda2_line_interpolator + class dda2_line_interpolator + { + public: + typedef int save_data_type; + enum save_size_e { save_size = 2 }; + + //-------------------------------------------------------------------- + dda2_line_interpolator() {} + + //-------------------------------------------- Forward-adjusted line + dda2_line_interpolator(int y1, int y2, int count) : + m_cnt(count <= 0 ? 1 : count), + m_lft((y2 - y1) / m_cnt), + m_rem((y2 - y1) % m_cnt), + m_mod(m_rem), + m_y(y1) + { + if(m_mod <= 0) + { + m_mod += count; + m_rem += count; + m_lft--; + } + m_mod -= count; + } + + //-------------------------------------------- Backward-adjusted line + dda2_line_interpolator(int y1, int y2, int count, int) : + m_cnt(count <= 0 ? 1 : count), + m_lft((y2 - y1) / m_cnt), + m_rem((y2 - y1) % m_cnt), + m_mod(m_rem), + m_y(y1) + { + if(m_mod <= 0) + { + m_mod += count; + m_rem += count; + m_lft--; + } + } + + //-------------------------------------------- Backward-adjusted line + dda2_line_interpolator(int y, int count) : + m_cnt(count <= 0 ? 1 : count), + m_lft(y / m_cnt), + m_rem(y % m_cnt), + m_mod(m_rem), + m_y(0) + { + if(m_mod <= 0) + { + m_mod += count; + m_rem += count; + m_lft--; + } + } + + + //-------------------------------------------------------------------- + void save(save_data_type* data) const + { + data[0] = m_mod; + data[1] = m_y; + } + + //-------------------------------------------------------------------- + void load(const save_data_type* data) + { + m_mod = data[0]; + m_y = data[1]; + } + + //-------------------------------------------------------------------- + void operator++() + { + m_mod += m_rem; + m_y += m_lft; + if(m_mod > 0) + { + m_mod -= m_cnt; + m_y++; + } + } + + //-------------------------------------------------------------------- + void operator--() + { + if(m_mod <= m_rem) + { + m_mod += m_cnt; + m_y--; + } + m_mod -= m_rem; + m_y -= m_lft; + } + + //-------------------------------------------------------------------- + void adjust_forward() + { + m_mod -= m_cnt; + } + + //-------------------------------------------------------------------- + void adjust_backward() + { + m_mod += m_cnt; + } + + //-------------------------------------------------------------------- + int mod() const { return m_mod; } + int rem() const { return m_rem; } + int lft() const { return m_lft; } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + + private: + int m_cnt; + int m_lft; + int m_rem; + int m_mod; + int m_y; + }; + + + + + + + + //---------------------------------------------line_bresenham_interpolator + class line_bresenham_interpolator + { + public: + enum subpixel_scale_e + { + subpixel_shift = 8, + subpixel_scale = 1 << subpixel_shift, + subpixel_mask = subpixel_scale - 1 + }; + + //-------------------------------------------------------------------- + static int line_lr(int v) { return v >> subpixel_shift; } + + //-------------------------------------------------------------------- + line_bresenham_interpolator(int x1, int y1, int x2, int y2) : + m_x1_lr(line_lr(x1)), + m_y1_lr(line_lr(y1)), + m_x2_lr(line_lr(x2)), + m_y2_lr(line_lr(y2)), + m_ver(std::abs(m_x2_lr - m_x1_lr) < std::abs(m_y2_lr - m_y1_lr)), + m_len(m_ver ? std::abs(m_y2_lr - m_y1_lr) : + std::abs(m_x2_lr - m_x1_lr)), + m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)), + m_interpolator(m_ver ? x1 : y1, + m_ver ? x2 : y2, + m_len) + { + } + + //-------------------------------------------------------------------- + bool is_ver() const { return m_ver; } + unsigned len() const { return m_len; } + int inc() const { return m_inc; } + + //-------------------------------------------------------------------- + void hstep() + { + ++m_interpolator; + m_x1_lr += m_inc; + } + + //-------------------------------------------------------------------- + void vstep() + { + ++m_interpolator; + m_y1_lr += m_inc; + } + + //-------------------------------------------------------------------- + int x1() const { return m_x1_lr; } + int y1() const { return m_y1_lr; } + int x2() const { return line_lr(m_interpolator.y()); } + int y2() const { return line_lr(m_interpolator.y()); } + int x2_hr() const { return m_interpolator.y(); } + int y2_hr() const { return m_interpolator.y(); } + + private: + int m_x1_lr; + int m_y1_lr; + int m_x2_lr; + int m_y2_lr; + bool m_ver; + unsigned m_len; + int m_inc; + dda2_line_interpolator m_interpolator; + + }; + + +} + + + +#endif diff --git a/include/agg_ellipse.h b/include/agg_ellipse.h new file mode 100644 index 0000000..b046b1c --- /dev/null +++ b/include/agg_ellipse.h @@ -0,0 +1,123 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class ellipse +// +//---------------------------------------------------------------------------- + +#ifndef AGG_ELLIPSE_INCLUDED +#define AGG_ELLIPSE_INCLUDED + +#include "agg_basics.h" +#include <cmath> + +namespace agg +{ + + //----------------------------------------------------------------ellipse + class ellipse + { + public: + ellipse() : + m_x(0.0), m_y(0.0), m_rx(1.0), m_ry(1.0), m_scale(1.0), + m_num(4), m_step(0), m_cw(false) {} + + ellipse(double x, double y, double rx, double ry, + unsigned num_steps=0, bool cw=false) : + m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0), + m_num(num_steps), m_step(0), m_cw(cw) + { + if(m_num == 0) calc_num_steps(); + } + + void init(double x, double y, double rx, double ry, + unsigned num_steps=0, bool cw=false); + + void approximation_scale(double scale); + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + void calc_num_steps(); + + double m_x; + double m_y; + double m_rx; + double m_ry; + double m_scale; + unsigned m_num; + unsigned m_step; + bool m_cw; + }; + + //------------------------------------------------------------------------ + inline void ellipse::init(double x, double y, double rx, double ry, + unsigned num_steps, bool cw) + { + m_x = x; + m_y = y; + m_rx = rx; + m_ry = ry; + m_num = num_steps; + m_step = 0; + m_cw = cw; + if(m_num == 0) calc_num_steps(); + } + + //------------------------------------------------------------------------ + inline void ellipse::approximation_scale(double scale) + { + m_scale = scale; + calc_num_steps(); + } + + //------------------------------------------------------------------------ + inline void ellipse::calc_num_steps() + { + double ra = (std::fabs(m_rx) + std::fabs(m_ry)) / 2; + double da = std::acos(ra / (ra + 0.125 / m_scale)) * 2; + m_num = uround(2*pi / da); + } + + //------------------------------------------------------------------------ + inline void ellipse::rewind(unsigned) + { + m_step = 0; + } + + //------------------------------------------------------------------------ + inline unsigned ellipse::vertex(double* x, double* y) + { + if(m_step == m_num) + { + ++m_step; + return path_cmd_end_poly | path_flags_close | path_flags_ccw; + } + if(m_step > m_num) return path_cmd_stop; + double angle = double(m_step) / double(m_num) * 2.0 * pi; + if(m_cw) angle = 2.0 * pi - angle; + *x = m_x + std::cos(angle) * m_rx; + *y = m_y + std::sin(angle) * m_ry; + m_step++; + return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to); + } + +} + + + +#endif + + diff --git a/include/agg_ellipse_bresenham.h b/include/agg_ellipse_bresenham.h new file mode 100644 index 0000000..ee3b9c4 --- /dev/null +++ b/include/agg_ellipse_bresenham.h @@ -0,0 +1,113 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Simple Bresenham interpolator for ellipsees +// +//---------------------------------------------------------------------------- + +#ifndef AGG_ELLIPSE_BRESENHAM_INCLUDED +#define AGG_ELLIPSE_BRESENHAM_INCLUDED + + +#include "agg_basics.h" + + +namespace agg +{ + + //------------------------------------------ellipse_bresenham_interpolator + class ellipse_bresenham_interpolator + { + public: + ellipse_bresenham_interpolator(int rx, int ry) : + m_rx2(rx * rx), + m_ry2(ry * ry), + m_two_rx2(m_rx2 << 1), + m_two_ry2(m_ry2 << 1), + m_dx(0), + m_dy(0), + m_inc_x(0), + m_inc_y(-ry * m_two_rx2), + m_cur_f(0) + {} + + int dx() const { return m_dx; } + int dy() const { return m_dy; } + + void operator++ () + { + int mx, my, mxy, min_m; + int fx, fy, fxy; + + mx = fx = m_cur_f + m_inc_x + m_ry2; + if(mx < 0) mx = -mx; + + my = fy = m_cur_f + m_inc_y + m_rx2; + if(my < 0) my = -my; + + mxy = fxy = m_cur_f + m_inc_x + m_ry2 + m_inc_y + m_rx2; + if(mxy < 0) mxy = -mxy; + + min_m = mx; + bool flag = true; + + if(min_m > my) + { + min_m = my; + flag = false; + } + + m_dx = m_dy = 0; + + if(min_m > mxy) + { + m_inc_x += m_two_ry2; + m_inc_y += m_two_rx2; + m_cur_f = fxy; + m_dx = 1; + m_dy = 1; + return; + } + + if(flag) + { + m_inc_x += m_two_ry2; + m_cur_f = fx; + m_dx = 1; + return; + } + + m_inc_y += m_two_rx2; + m_cur_f = fy; + m_dy = 1; + } + + private: + int m_rx2; + int m_ry2; + int m_two_rx2; + int m_two_ry2; + int m_dx; + int m_dy; + int m_inc_x; + int m_inc_y; + int m_cur_f; + + }; + +} + +#endif + diff --git a/include/agg_embedded_raster_fonts.h b/include/agg_embedded_raster_fonts.h new file mode 100644 index 0000000..9d522d6 --- /dev/null +++ b/include/agg_embedded_raster_fonts.h @@ -0,0 +1,59 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_EMBEDDED_RASTER_FONTS_INCLUDED +#define AGG_EMBEDDED_RASTER_FONTS_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + extern const int8u gse4x6[]; + extern const int8u gse4x8[]; + extern const int8u gse5x7[]; + extern const int8u gse5x9[]; + extern const int8u gse6x12[]; + extern const int8u gse6x9[]; + extern const int8u gse7x11[]; + extern const int8u gse7x11_bold[]; + extern const int8u gse7x15[]; + extern const int8u gse7x15_bold[]; + extern const int8u gse8x16[]; + extern const int8u gse8x16_bold[]; + extern const int8u mcs11_prop[]; + extern const int8u mcs11_prop_condensed[]; + extern const int8u mcs12_prop[]; + extern const int8u mcs13_prop[]; + extern const int8u mcs5x10_mono[]; + extern const int8u mcs5x11_mono[]; + extern const int8u mcs6x10_mono[]; + extern const int8u mcs6x11_mono[]; + extern const int8u mcs7x12_mono_high[]; + extern const int8u mcs7x12_mono_low[]; + extern const int8u verdana12[]; + extern const int8u verdana12_bold[]; + extern const int8u verdana13[]; + extern const int8u verdana13_bold[]; + extern const int8u verdana14[]; + extern const int8u verdana14_bold[]; + extern const int8u verdana16[]; + extern const int8u verdana16_bold[]; + extern const int8u verdana17[]; + extern const int8u verdana17_bold[]; + extern const int8u verdana18[]; + extern const int8u verdana18_bold[]; +} + +#endif diff --git a/include/agg_font_cache_manager.h b/include/agg_font_cache_manager.h new file mode 100644 index 0000000..4f362d1 --- /dev/null +++ b/include/agg_font_cache_manager.h @@ -0,0 +1,409 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_FONT_CACHE_MANAGER_INCLUDED +#define AGG_FONT_CACHE_MANAGER_INCLUDED + +#include <cstring> +#include "agg_array.h" + +namespace agg +{ + + //---------------------------------------------------------glyph_data_type + enum glyph_data_type + { + glyph_data_invalid = 0, + glyph_data_mono = 1, + glyph_data_gray8 = 2, + glyph_data_outline = 3 + }; + + + //-------------------------------------------------------------glyph_cache + struct glyph_cache + { + unsigned glyph_index; + int8u* data; + unsigned data_size; + glyph_data_type data_type; + rect_i bounds; + double advance_x; + double advance_y; + }; + + + //--------------------------------------------------------------font_cache + class font_cache + { + public: + enum block_size_e { block_size = 16384-16 }; + + //-------------------------------------------------------------------- + font_cache() : + m_allocator(block_size), + m_font_signature(0) + {} + + //-------------------------------------------------------------------- + void signature(const char* font_signature) + { + m_font_signature = (char*)m_allocator.allocate(std::strlen(font_signature) + 1); + std::strcpy(m_font_signature, font_signature); + std::memset(m_glyphs, 0, sizeof(m_glyphs)); + } + + //-------------------------------------------------------------------- + bool font_is(const char* font_signature) const + { + return std::strcmp(font_signature, m_font_signature) == 0; + } + + //-------------------------------------------------------------------- + const glyph_cache* find_glyph(unsigned glyph_code) const + { + unsigned msb = (glyph_code >> 8) & 0xFF; + if(m_glyphs[msb]) + { + return m_glyphs[msb][glyph_code & 0xFF]; + } + return 0; + } + + //-------------------------------------------------------------------- + glyph_cache* cache_glyph(unsigned glyph_code, + unsigned glyph_index, + unsigned data_size, + glyph_data_type data_type, + const rect_i& bounds, + double advance_x, + double advance_y) + { + unsigned msb = (glyph_code >> 8) & 0xFF; + if(m_glyphs[msb] == 0) + { + m_glyphs[msb] = + (glyph_cache**)m_allocator.allocate(sizeof(glyph_cache*) * 256, + sizeof(glyph_cache*)); + std::memset(m_glyphs[msb], 0, sizeof(glyph_cache*) * 256); + } + + unsigned lsb = glyph_code & 0xFF; + if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite + + glyph_cache* glyph = + (glyph_cache*)m_allocator.allocate(sizeof(glyph_cache), + sizeof(double)); + + glyph->glyph_index = glyph_index; + glyph->data = m_allocator.allocate(data_size); + glyph->data_size = data_size; + glyph->data_type = data_type; + glyph->bounds = bounds; + glyph->advance_x = advance_x; + glyph->advance_y = advance_y; + return m_glyphs[msb][lsb] = glyph; + } + + private: + block_allocator m_allocator; + glyph_cache** m_glyphs[256]; + char* m_font_signature; + }; + + + + + + + + //---------------------------------------------------------font_cache_pool + class font_cache_pool + { + public: + //-------------------------------------------------------------------- + ~font_cache_pool() + { + unsigned i; + for(i = 0; i < m_num_fonts; ++i) + { + obj_allocator<font_cache>::deallocate(m_fonts[i]); + } + pod_allocator<font_cache*>::deallocate(m_fonts, m_max_fonts); + } + + //-------------------------------------------------------------------- + font_cache_pool(unsigned max_fonts=32) : + m_fonts(pod_allocator<font_cache*>::allocate(max_fonts)), + m_max_fonts(max_fonts), + m_num_fonts(0), + m_cur_font(0) + {} + + + //-------------------------------------------------------------------- + void font(const char* font_signature, bool reset_cache = false) + { + int idx = find_font(font_signature); + if(idx >= 0) + { + if(reset_cache) + { + obj_allocator<font_cache>::deallocate(m_fonts[idx]); + m_fonts[idx] = obj_allocator<font_cache>::allocate(); + m_fonts[idx]->signature(font_signature); + } + m_cur_font = m_fonts[idx]; + } + else + { + if(m_num_fonts >= m_max_fonts) + { + obj_allocator<font_cache>::deallocate(m_fonts[0]); + std::memcpy(m_fonts, + m_fonts + 1, + (m_max_fonts - 1) * sizeof(font_cache*)); + m_num_fonts = m_max_fonts - 1; + } + m_fonts[m_num_fonts] = obj_allocator<font_cache>::allocate(); + m_fonts[m_num_fonts]->signature(font_signature); + m_cur_font = m_fonts[m_num_fonts]; + ++m_num_fonts; + } + } + + //-------------------------------------------------------------------- + const font_cache* font() const + { + return m_cur_font; + } + + //-------------------------------------------------------------------- + const glyph_cache* find_glyph(unsigned glyph_code) const + { + if(m_cur_font) return m_cur_font->find_glyph(glyph_code); + return 0; + } + + //-------------------------------------------------------------------- + glyph_cache* cache_glyph(unsigned glyph_code, + unsigned glyph_index, + unsigned data_size, + glyph_data_type data_type, + const rect_i& bounds, + double advance_x, + double advance_y) + { + if(m_cur_font) + { + return m_cur_font->cache_glyph(glyph_code, + glyph_index, + data_size, + data_type, + bounds, + advance_x, + advance_y); + } + return 0; + } + + + //-------------------------------------------------------------------- + int find_font(const char* font_signature) + { + unsigned i; + for(i = 0; i < m_num_fonts; i++) + { + if(m_fonts[i]->font_is(font_signature)) return int(i); + } + return -1; + } + + private: + font_cache** m_fonts; + unsigned m_max_fonts; + unsigned m_num_fonts; + font_cache* m_cur_font; + }; + + + + + //------------------------------------------------------------------------ + enum glyph_rendering + { + glyph_ren_native_mono, + glyph_ren_native_gray8, + glyph_ren_outline, + glyph_ren_agg_mono, + glyph_ren_agg_gray8 + }; + + + + + //------------------------------------------------------font_cache_manager + template<class FontEngine> class font_cache_manager + { + public: + typedef FontEngine font_engine_type; + typedef font_cache_manager<FontEngine> self_type; + typedef typename font_engine_type::path_adaptor_type path_adaptor_type; + typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type; + typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type; + typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type; + typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type; + + //-------------------------------------------------------------------- + font_cache_manager(font_engine_type& engine, unsigned max_fonts=32) : + m_fonts(max_fonts), + m_engine(engine), + m_change_stamp(-1), + m_prev_glyph(0), + m_last_glyph(0) + {} + + //-------------------------------------------------------------------- + void reset_last_glyph() + { + m_prev_glyph = m_last_glyph = 0; + } + + //-------------------------------------------------------------------- + const glyph_cache* glyph(unsigned glyph_code) + { + synchronize(); + const glyph_cache* gl = m_fonts.find_glyph(glyph_code); + if(gl) + { + m_prev_glyph = m_last_glyph; + return m_last_glyph = gl; + } + else + { + if(m_engine.prepare_glyph(glyph_code)) + { + m_prev_glyph = m_last_glyph; + m_last_glyph = m_fonts.cache_glyph(glyph_code, + m_engine.glyph_index(), + m_engine.data_size(), + m_engine.data_type(), + m_engine.bounds(), + m_engine.advance_x(), + m_engine.advance_y()); + m_engine.write_glyph_to(m_last_glyph->data); + return m_last_glyph; + } + } + return 0; + } + + //-------------------------------------------------------------------- + void init_embedded_adaptors(const glyph_cache* gl, + double x, double y, + double scale=1.0) + { + if(gl) + { + switch(gl->data_type) + { + default: return; + case glyph_data_mono: + m_mono_adaptor.init(gl->data, gl->data_size, x, y); + break; + + case glyph_data_gray8: + m_gray8_adaptor.init(gl->data, gl->data_size, x, y); + break; + + case glyph_data_outline: + m_path_adaptor.init(gl->data, gl->data_size, x, y, scale); + break; + } + } + } + + + //-------------------------------------------------------------------- + path_adaptor_type& path_adaptor() { return m_path_adaptor; } + gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; } + gray8_scanline_type& gray8_scanline() { return m_gray8_scanline; } + mono_adaptor_type& mono_adaptor() { return m_mono_adaptor; } + mono_scanline_type& mono_scanline() { return m_mono_scanline; } + + //-------------------------------------------------------------------- + const glyph_cache* perv_glyph() const { return m_prev_glyph; } + const glyph_cache* last_glyph() const { return m_last_glyph; } + + //-------------------------------------------------------------------- + bool add_kerning(double* x, double* y) + { + if(m_prev_glyph && m_last_glyph) + { + return m_engine.add_kerning(m_prev_glyph->glyph_index, + m_last_glyph->glyph_index, + x, y); + } + return false; + } + + //-------------------------------------------------------------------- + void precache(unsigned from, unsigned to) + { + for(; from <= to; ++from) glyph(from); + } + + //-------------------------------------------------------------------- + void reset_cache() + { + m_fonts.font(m_engine.font_signature(), true); + m_change_stamp = m_engine.change_stamp(); + m_prev_glyph = m_last_glyph = 0; + } + + private: + //-------------------------------------------------------------------- + font_cache_manager(const self_type&); + const self_type& operator = (const self_type&); + + //-------------------------------------------------------------------- + void synchronize() + { + if(m_change_stamp != m_engine.change_stamp()) + { + m_fonts.font(m_engine.font_signature()); + m_change_stamp = m_engine.change_stamp(); + m_prev_glyph = m_last_glyph = 0; + } + } + + font_cache_pool m_fonts; + font_engine_type& m_engine; + int m_change_stamp; + double m_dx; + double m_dy; + const glyph_cache* m_prev_glyph; + const glyph_cache* m_last_glyph; + path_adaptor_type m_path_adaptor; + gray8_adaptor_type m_gray8_adaptor; + gray8_scanline_type m_gray8_scanline; + mono_adaptor_type m_mono_adaptor; + mono_scanline_type m_mono_scanline; + }; + +} + +#endif + diff --git a/include/agg_font_cache_manager2.h b/include/agg_font_cache_manager2.h new file mode 100644 index 0000000..9439442 --- /dev/null +++ b/include/agg_font_cache_manager2.h @@ -0,0 +1,311 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_FONT_CACHE_MANAGER2_INCLUDED +#define AGG_FONT_CACHE_MANAGER2_INCLUDED + +#include <cassert> +#include <exception> +#include <cstring> +#include "agg_array.h" + +namespace agg { + +namespace fman { + //---------------------------------------------------------glyph_data_type + enum glyph_data_type + { + glyph_data_invalid = 0, + glyph_data_mono = 1, + glyph_data_gray8 = 2, + glyph_data_outline = 3 + }; + + + //-------------------------------------------------------------cached_glyph + struct cached_glyph + { + void * cached_font; + unsigned glyph_code; + unsigned glyph_index; + int8u* data; + unsigned data_size; + glyph_data_type data_type; + rect_i bounds; + double advance_x; + double advance_y; + }; + + + //--------------------------------------------------------------cached_glyphs + class cached_glyphs + { + public: + enum block_size_e { block_size = 16384-16 }; + + //-------------------------------------------------------------------- + cached_glyphs() + : m_allocator(block_size) + { std::memset(m_glyphs, 0, sizeof(m_glyphs)); } + + //-------------------------------------------------------------------- + const cached_glyph* find_glyph(unsigned glyph_code) const + { + unsigned msb = (glyph_code >> 8) & 0xFF; + if(m_glyphs[msb]) + { + return m_glyphs[msb][glyph_code & 0xFF]; + } + return 0; + } + + //-------------------------------------------------------------------- + cached_glyph* cache_glyph( + void * cached_font, + unsigned glyph_code, + unsigned glyph_index, + unsigned data_size, + glyph_data_type data_type, + const rect_i& bounds, + double advance_x, + double advance_y) + { + unsigned msb = (glyph_code >> 8) & 0xFF; + if(m_glyphs[msb] == 0) + { + m_glyphs[msb] = + (cached_glyph**)m_allocator.allocate(sizeof(cached_glyph*) * 256, + sizeof(cached_glyph*)); + std::memset(m_glyphs[msb], 0, sizeof(cached_glyph*) * 256); + } + + unsigned lsb = glyph_code & 0xFF; + if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite + + cached_glyph* glyph = + (cached_glyph*)m_allocator.allocate(sizeof(cached_glyph), + sizeof(double)); + + glyph->cached_font = cached_font; + glyph->glyph_code = glyph_code; + glyph->glyph_index = glyph_index; + glyph->data = m_allocator.allocate(data_size); + glyph->data_size = data_size; + glyph->data_type = data_type; + glyph->bounds = bounds; + glyph->advance_x = advance_x; + glyph->advance_y = advance_y; + return m_glyphs[msb][lsb] = glyph; + } + + private: + block_allocator m_allocator; + cached_glyph** m_glyphs[256]; + }; + + + + //------------------------------------------------------------------------ + enum glyph_rendering + { + glyph_ren_native_mono, + glyph_ren_native_gray8, + glyph_ren_outline, + glyph_ren_agg_mono, + glyph_ren_agg_gray8 + }; + + + + + //------------------------------------------------------font_cache_manager + template<class FontEngine> class font_cache_manager + { + public: + typedef FontEngine font_engine_type; + typedef font_cache_manager<FontEngine> self_type; + typedef typename font_engine_type::path_adaptor_type path_adaptor_type; + typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type; + typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type; + typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type; + typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type; + + struct cached_font + { + cached_font( + font_engine_type& engine, + typename FontEngine::loaded_face *face, + double height, + double width, + bool hinting, + glyph_rendering rendering ) + : m_engine( engine ) + , m_face( face ) + , m_height( height ) + , m_width( width ) + , m_hinting( hinting ) + , m_rendering( rendering ) + { + select_face(); + m_face_height=m_face->height(); + m_face_width=m_face->width(); + m_face_ascent=m_face->ascent(); + m_face_descent=m_face->descent(); + m_face_ascent_b=m_face->ascent_b(); + m_face_descent_b=m_face->descent_b(); + } + + double height() const + { + return m_face_height; + } + + double width() const + { + return m_face_width; + } + + double ascent() const + { + return m_face_ascent; + } + + double descent() const + { + return m_face_descent; + } + + double ascent_b() const + { + return m_face_ascent_b; + } + + double descent_b() const + { + return m_face_descent_b; + } + + bool add_kerning( const cached_glyph *first, const cached_glyph *second, double* x, double* y) + { + if( !first || !second ) + return false; + select_face(); + return m_face->add_kerning( + first->glyph_index, second->glyph_index, x, y ); + } + + void select_face() + { + m_face->select_instance( m_height, m_width, m_hinting, m_rendering ); + } + + const cached_glyph *get_glyph(unsigned cp) + { + const cached_glyph *glyph=m_glyphs.find_glyph(cp); + if( glyph==0 ) + { + typename FontEngine::prepared_glyph prepared; + select_face(); + bool success=m_face->prepare_glyph(cp, &prepared); + if( success ) + { + glyph=m_glyphs.cache_glyph( + this, + prepared.glyph_code, + prepared.glyph_index, + prepared.data_size, + prepared.data_type, + prepared.bounds, + prepared.advance_x, + prepared.advance_y ); + assert( glyph!=0 ); + m_face->write_glyph_to(&prepared,glyph->data); + } + } + return glyph; + } + + font_engine_type& m_engine; + typename FontEngine::loaded_face *m_face; + double m_height; + double m_width; + bool m_hinting; + glyph_rendering m_rendering; + double m_face_height; + double m_face_width; + double m_face_ascent; + double m_face_descent; + double m_face_ascent_b; + double m_face_descent_b; + cached_glyphs m_glyphs; + }; + + //-------------------------------------------------------------------- + font_cache_manager(font_engine_type& engine, unsigned max_fonts=32) + :m_engine(engine) + { } + + //-------------------------------------------------------------------- + void init_embedded_adaptors(const cached_glyph* gl, + double x, double y, + double scale=1.0) + { + if(gl) + { + switch(gl->data_type) + { + default: return; + case glyph_data_mono: + m_mono_adaptor.init(gl->data, gl->data_size, x, y); + break; + + case glyph_data_gray8: + m_gray8_adaptor.init(gl->data, gl->data_size, x, y); + break; + + case glyph_data_outline: + m_path_adaptor.init(gl->data, gl->data_size, x, y, scale); + break; + } + } + } + + + //-------------------------------------------------------------------- + path_adaptor_type& path_adaptor() { return m_path_adaptor; } + gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; } + gray8_scanline_type& gray8_scanline() { return m_gray8_scanline; } + mono_adaptor_type& mono_adaptor() { return m_mono_adaptor; } + mono_scanline_type& mono_scanline() { return m_mono_scanline; } + + + private: + //-------------------------------------------------------------------- + font_cache_manager(const self_type&); + const self_type& operator = (const self_type&); + + font_engine_type& m_engine; + path_adaptor_type m_path_adaptor; + gray8_adaptor_type m_gray8_adaptor; + gray8_scanline_type m_gray8_scanline; + mono_adaptor_type m_mono_adaptor; + mono_scanline_type m_mono_scanline; + }; + +} +} + +#endif + diff --git a/include/agg_gamma_functions.h b/include/agg_gamma_functions.h new file mode 100644 index 0000000..a29081d --- /dev/null +++ b/include/agg_gamma_functions.h @@ -0,0 +1,131 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_GAMMA_FUNCTIONS_INCLUDED +#define AGG_GAMMA_FUNCTIONS_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //===============================================================gamma_none + struct gamma_none + { + double operator()(double x) const { return x; } + }; + + + //==============================================================gamma_power + class gamma_power + { + public: + gamma_power() : m_gamma(1.0) {} + gamma_power(double g) : m_gamma(g) {} + + void gamma(double g) { m_gamma = g; } + double gamma() const { return m_gamma; } + + double operator() (double x) const + { + return pow(x, m_gamma); + } + + private: + double m_gamma; + }; + + + //==========================================================gamma_threshold + class gamma_threshold + { + public: + gamma_threshold() : m_threshold(0.5) {} + gamma_threshold(double t) : m_threshold(t) {} + + void threshold(double t) { m_threshold = t; } + double threshold() const { return m_threshold; } + + double operator() (double x) const + { + return (x < m_threshold) ? 0.0 : 1.0; + } + + private: + double m_threshold; + }; + + + //============================================================gamma_linear + class gamma_linear + { + public: + gamma_linear() : m_start(0.0), m_end(1.0) {} + gamma_linear(double s, double e) : m_start(s), m_end(e) {} + + void set(double s, double e) { m_start = s; m_end = e; } + void start(double s) { m_start = s; } + void end(double e) { m_end = e; } + double start() const { return m_start; } + double end() const { return m_end; } + + double operator() (double x) const + { + if(x < m_start) return 0.0; + if(x > m_end) return 1.0; + return (x - m_start) / (m_end - m_start); + } + + private: + double m_start; + double m_end; + }; + + + //==========================================================gamma_multiply + class gamma_multiply + { + public: + gamma_multiply() : m_mul(1.0) {} + gamma_multiply(double v) : m_mul(v) {} + + void value(double v) { m_mul = v; } + double value() const { return m_mul; } + + double operator() (double x) const + { + double y = x * m_mul; + if(y > 1.0) y = 1.0; + return y; + } + + private: + double m_mul; + }; + + inline double sRGB_to_linear(double x) + { + return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4); + } + + inline double linear_to_sRGB(double x) + { + return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055); + } +} + +#endif + + + diff --git a/include/agg_gamma_lut.h b/include/agg_gamma_lut.h new file mode 100644 index 0000000..52e6140 --- /dev/null +++ b/include/agg_gamma_lut.h @@ -0,0 +1,307 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_GAMMA_LUT_INCLUDED +#define AGG_GAMMA_LUT_INCLUDED + +#include <cmath> +#include "agg_basics.h" +#include "agg_gamma_functions.h" + +namespace agg +{ + template<class LoResT=int8u, + class HiResT=int8u, + unsigned GammaShift=8, + unsigned HiResShift=8> class gamma_lut + { + public: + typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type; + + enum gamma_scale_e + { + gamma_shift = GammaShift, + gamma_size = 1 << gamma_shift, + gamma_mask = gamma_size - 1 + }; + + enum hi_res_scale_e + { + hi_res_shift = HiResShift, + hi_res_size = 1 << hi_res_shift, + hi_res_mask = hi_res_size - 1 + }; + + ~gamma_lut() + { + pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size); + pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size); + } + + gamma_lut() : + m_gamma(1.0), + m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)), + m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size)) + { + unsigned i; + for(i = 0; i < gamma_size; i++) + { + m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift)); + } + + for(i = 0; i < hi_res_size; i++) + { + m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift)); + } + } + + gamma_lut(double g) : + m_gamma(1.0), + m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)), + m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size)) + { + gamma(g); + } + + void gamma(double g) + { + m_gamma = g; + + unsigned i; + for(i = 0; i < gamma_size; i++) + { + m_dir_gamma[i] = (HiResT) + uround(std::pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask)); + } + + double inv_g = 1.0 / g; + for(i = 0; i < hi_res_size; i++) + { + m_inv_gamma[i] = (LoResT) + uround(std::pow(i / double(hi_res_mask), inv_g) * double(gamma_mask)); + } + } + + double gamma() const + { + return m_gamma; + } + + HiResT dir(LoResT v) const + { + return m_dir_gamma[unsigned(v)]; + } + + LoResT inv(HiResT v) const + { + return m_inv_gamma[unsigned(v)]; + } + + private: + gamma_lut(const self_type&); + const self_type& operator = (const self_type&); + + double m_gamma; + HiResT* m_dir_gamma; + LoResT* m_inv_gamma; + }; + + // + // sRGB support classes + // + + // Optimized sRGB lookup table. The direct conversion (sRGB to linear) + // is a straightforward lookup. The inverse conversion (linear to sRGB) + // is implemented using binary search. + template<class LinearType> + class sRGB_lut_base + { + public: + LinearType dir(int8u v) const + { + return m_dir_table[v]; + } + + int8u inv(LinearType v) const + { + // Unrolled binary search. + int8u x = 0; + if (v > m_inv_table[128]) x = 128; + if (v > m_inv_table[x + 64]) x += 64; + if (v > m_inv_table[x + 32]) x += 32; + if (v > m_inv_table[x + 16]) x += 16; + if (v > m_inv_table[x + 8]) x += 8; + if (v > m_inv_table[x + 4]) x += 4; + if (v > m_inv_table[x + 2]) x += 2; + if (v > m_inv_table[x + 1]) x += 1; + return x; + } + + protected: + LinearType m_dir_table[256]; + LinearType m_inv_table[256]; + + // Only derived classes may instantiate. + sRGB_lut_base() + { + } + }; + + + // sRGB_lut - implements sRGB conversion for the various types. + // Base template is undefined, specializations are provided below. + template<class LinearType> + class sRGB_lut; + + template<> + class sRGB_lut<float> : public sRGB_lut_base<float> + { + public: + sRGB_lut() + { + // Generate lookup tables. + m_dir_table[0] = 0; + m_inv_table[0] = 0; + for (unsigned i = 1; i <= 255; ++i) + { + // Floating-point RGB is in range [0,1]. + m_dir_table[i] = float(sRGB_to_linear(i / 255.0)); + m_inv_table[i] = float(sRGB_to_linear((i - 0.5) / 255.0)); + } + } + }; + + template<> + class sRGB_lut<int16u> : public sRGB_lut_base<int16u> + { + public: + sRGB_lut() + { + // Generate lookup tables. + m_dir_table[0] = 0; + m_inv_table[0] = 0; + for (int i = 1; i <= 255; ++i) + { + // 16-bit RGB is in range [0,65535]. + m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0)); + m_inv_table[i] = uround(65535.0 * sRGB_to_linear((i - 0.5) / 255.0)); + } + } + }; + + template<> + class sRGB_lut<int8u> : public sRGB_lut_base<int8u> + { + public: + sRGB_lut() + { + // Generate lookup tables. + m_dir_table[0] = 0; + m_inv_table[0] = 0; + for (int i = 1; i <= 255; ++i) + { + // 8-bit RGB is handled with simple bidirectional lookup tables. + m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0)); + m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0)); + } + } + + int8u inv(int8u v) const + { + // In this case, the inverse transform is a simple lookup. + return m_inv_table[v]; + } + }; + + // Common base class for sRGB_conv objects. Defines an internal + // sRGB_lut object so that users don't have to. + template<class T> + class sRGB_conv_base + { + public: + static T rgb_from_sRGB(int8u x) + { + return lut.dir(x); + } + + static int8u rgb_to_sRGB(T x) + { + return lut.inv(x); + } + + private: + static sRGB_lut<T> lut; + }; + + // Definition of sRGB_conv_base::lut. Due to the fact that this a template, + // we don't need to place the definition in a cpp file. Hurrah. + template<class T> + sRGB_lut<T> sRGB_conv_base<T>::lut; + + // Wrapper for sRGB-linear conversion. + // Base template is undefined, specializations are provided below. + template<class T> + class sRGB_conv; + + template<> + class sRGB_conv<float> : public sRGB_conv_base<float> + { + public: + static float alpha_from_sRGB(int8u x) + { + static const double y = 1 / 255.0; + return float(x * y); + } + + static int8u alpha_to_sRGB(float x) + { + if (x < 0) return 0; + if (x > 1) return 255; + return int8u(0.5 + x * 255); + } + }; + + template<> + class sRGB_conv<int16u> : public sRGB_conv_base<int16u> + { + public: + static int16u alpha_from_sRGB(int8u x) + { + return (x << 8) | x; + } + + static int8u alpha_to_sRGB(int16u x) + { + return x >> 8; + } + }; + + template<> + class sRGB_conv<int8u> : public sRGB_conv_base<int8u> + { + public: + static int8u alpha_from_sRGB(int8u x) + { + return x; + } + + static int8u alpha_to_sRGB(int8u x) + { + return x; + } + }; +} + +#endif diff --git a/include/agg_glyph_raster_bin.h b/include/agg_glyph_raster_bin.h new file mode 100644 index 0000000..57d5b98 --- /dev/null +++ b/include/agg_glyph_raster_bin.h @@ -0,0 +1,155 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_GLYPH_RASTER_BIN_INCLUDED +#define AGG_GLYPH_RASTER_BIN_INCLUDED + +#include <cstring> +#include "agg_basics.h" + +namespace agg +{ + + //========================================================glyph_raster_bin + template<class ColorT> class glyph_raster_bin + { + public: + typedef ColorT color_type; + + //-------------------------------------------------------------------- + struct glyph_rect + { + int x1,y1,x2,y2; + double dx, dy; + }; + + //-------------------------------------------------------------------- + glyph_raster_bin(const int8u* font) : + m_font(font), + m_big_endian(false) + { + int t = 1; + if(*(char*)&t == 0) m_big_endian = true; + std::memset(m_span, 0, sizeof(m_span)); + } + + //-------------------------------------------------------------------- + const int8u* font() const { return m_font; } + void font(const int8u* f) { m_font = f; } + + //-------------------------------------------------------------------- + double height() const { return m_font[0]; } + double base_line() const { return m_font[1]; } + + //-------------------------------------------------------------------- + template<class CharT> + double width(const CharT* str) const + { + unsigned start_char = m_font[2]; + unsigned num_chars = m_font[3]; + + unsigned w = 0; + while(*str) + { + unsigned glyph = *str; + const int8u* bits = m_font + 4 + num_chars * 2 + + value(m_font + 4 + (glyph - start_char) * 2); + w += *bits; + ++str; + } + return w; + } + + //-------------------------------------------------------------------- + void prepare(glyph_rect* r, double x, double y, unsigned glyph, bool flip) + { + unsigned start_char = m_font[2]; + unsigned num_chars = m_font[3]; + + m_bits = m_font + 4 + num_chars * 2 + + value(m_font + 4 + (glyph - start_char) * 2); + + m_glyph_width = *m_bits++; + m_glyph_byte_width = (m_glyph_width + 7) >> 3; + + r->x1 = int(x); + r->x2 = r->x1 + m_glyph_width - 1; + if(flip) + { + r->y1 = int(y) - m_font[0] + m_font[1]; + r->y2 = r->y1 + m_font[0] - 1; + } + else + { + r->y1 = int(y) - m_font[1] + 1; + r->y2 = r->y1 + m_font[0] - 1; + } + r->dx = m_glyph_width; + r->dy = 0; + } + + //-------------------------------------------------------------------- + const cover_type* span(unsigned i) + { + i = m_font[0] - i - 1; + const int8u* bits = m_bits + i * m_glyph_byte_width; + unsigned j; + unsigned val = *bits; + unsigned nb = 0; + for(j = 0; j < m_glyph_width; ++j) + { + m_span[j] = (cover_type)((val & 0x80) ? cover_full : cover_none); + val <<= 1; + if(++nb >= 8) + { + val = *++bits; + nb = 0; + } + } + return m_span; + } + + private: + //-------------------------------------------------------------------- + int16u value(const int8u* p) const + { + int16u v; + if(m_big_endian) + { + *(int8u*)&v = p[1]; + *((int8u*)&v + 1) = p[0]; + } + else + { + *(int8u*)&v = p[0]; + *((int8u*)&v + 1) = p[1]; + } + return v; + } + + + //-------------------------------------------------------------------- + const int8u* m_font; + bool m_big_endian; + cover_type m_span[32]; + const int8u* m_bits; + unsigned m_glyph_width; + unsigned m_glyph_byte_width; + }; + + +} + +#endif diff --git a/include/agg_gradient_lut.h b/include/agg_gradient_lut.h new file mode 100644 index 0000000..9aaa426 --- /dev/null +++ b/include/agg_gradient_lut.h @@ -0,0 +1,244 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_GRADIENT_LUT_INCLUDED +#define AGG_GRADIENT_LUT_INCLUDED + +#include "agg_array.h" +#include "agg_dda_line.h" +#include "agg_color_rgba.h" +#include "agg_color_gray.h" + +namespace agg +{ + + //======================================================color_interpolator + template<class ColorT> struct color_interpolator + { + public: + typedef ColorT color_type; + + color_interpolator(const color_type& c1, + const color_type& c2, + unsigned len) : + m_c1(c1), + m_c2(c2), + m_len(len), + m_count(0) + {} + + void operator ++ () + { + ++m_count; + } + + color_type color() const + { + return m_c1.gradient(m_c2, double(m_count) / m_len); + } + + private: + color_type m_c1; + color_type m_c2; + unsigned m_len; + unsigned m_count; + }; + + //======================================================================== + // Fast specialization for rgba8 + template<> struct color_interpolator<rgba8> + { + public: + typedef rgba8 color_type; + + color_interpolator(const color_type& c1, + const color_type& c2, + unsigned len) : + r(c1.r, c2.r, len), + g(c1.g, c2.g, len), + b(c1.b, c2.b, len), + a(c1.a, c2.a, len) + {} + + void operator ++ () + { + ++r; ++g; ++b; ++a; + } + + color_type color() const + { + return color_type(r.y(), g.y(), b.y(), a.y()); + } + + private: + agg::dda_line_interpolator<14> r, g, b, a; + }; + + //======================================================================== + // Fast specialization for gray8 + template<> struct color_interpolator<gray8> + { + public: + typedef gray8 color_type; + + color_interpolator(const color_type& c1, + const color_type& c2, + unsigned len) : + v(c1.v, c2.v, len), + a(c1.a, c2.a, len) + {} + + void operator ++ () + { + ++v; ++a; + } + + color_type color() const + { + return color_type(v.y(), a.y()); + } + + private: + agg::dda_line_interpolator<14> v,a; + }; + + //============================================================gradient_lut + template<class ColorInterpolator, + unsigned ColorLutSize=256> class gradient_lut + { + public: + typedef ColorInterpolator interpolator_type; + typedef typename interpolator_type::color_type color_type; + enum { color_lut_size = ColorLutSize }; + + //-------------------------------------------------------------------- + gradient_lut() : m_color_lut(color_lut_size) {} + + // Build Gradient Lut + // First, call remove_all(), then add_color() at least twice, + // then build_lut(). Argument "offset" in add_color must be + // in range [0...1] and defines a color stop as it is described + // in SVG specification, section Gradients and Patterns. + // The simplest linear gradient is: + // gradient_lut.add_color(0.0, start_color); + // gradient_lut.add_color(1.0, end_color); + //-------------------------------------------------------------------- + void remove_all(); + void add_color(double offset, const color_type& color); + void build_lut(); + + // Size-index Interface. This class can be used directly as the + // ColorF in span_gradient. All it needs is two access methods + // size() and operator []. + //-------------------------------------------------------------------- + static unsigned size() + { + return color_lut_size; + } + const color_type& operator [] (unsigned i) const + { + return m_color_lut[i]; + } + + private: + //-------------------------------------------------------------------- + struct color_point + { + double offset; + color_type color; + + color_point() {} + color_point(double off, const color_type& c) : + offset(off), color(c) + { + if(offset < 0.0) offset = 0.0; + if(offset > 1.0) offset = 1.0; + } + }; + typedef agg::pod_bvector<color_point, 4> color_profile_type; + typedef agg::pod_array<color_type> color_lut_type; + + static bool offset_less(const color_point& a, const color_point& b) + { + return a.offset < b.offset; + } + static bool offset_equal(const color_point& a, const color_point& b) + { + return a.offset == b.offset; + } + + //-------------------------------------------------------------------- + color_profile_type m_color_profile; + color_lut_type m_color_lut; + }; + + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void gradient_lut<T,S>::remove_all() + { + m_color_profile.remove_all(); + } + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void gradient_lut<T,S>::add_color(double offset, const color_type& color) + { + m_color_profile.add(color_point(offset, color)); + } + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void gradient_lut<T,S>::build_lut() + { + quick_sort(m_color_profile, offset_less); + m_color_profile.cut_at(remove_duplicates(m_color_profile, offset_equal)); + if(m_color_profile.size() >= 2) + { + unsigned i; + unsigned start = uround(m_color_profile[0].offset * color_lut_size); + unsigned end; + color_type c = m_color_profile[0].color; + for(i = 0; i < start; i++) + { + m_color_lut[i] = c; + } + for(i = 1; i < m_color_profile.size(); i++) + { + end = uround(m_color_profile[i].offset * color_lut_size); + interpolator_type ci(m_color_profile[i-1].color, + m_color_profile[i ].color, + end - start + 1); + while(start < end) + { + m_color_lut[start] = ci.color(); + ++ci; + ++start; + } + } + c = m_color_profile.last().color; + for(; end < m_color_lut.size(); end++) + { + m_color_lut[end] = c; + } + } + } +} + + + + +#endif diff --git a/include/agg_gsv_text.h b/include/agg_gsv_text.h new file mode 100644 index 0000000..16b3aeb --- /dev/null +++ b/include/agg_gsv_text.h @@ -0,0 +1,153 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Class gsv_text +// +//---------------------------------------------------------------------------- + +#ifndef AGG_GSV_TEXT_INCLUDED +#define AGG_GSV_TEXT_INCLUDED + +#include "agg_array.h" +#include "agg_conv_stroke.h" +#include "agg_conv_transform.h" + +namespace agg +{ + + + //---------------------------------------------------------------gsv_text + // + // See Implementation agg_gsv_text.cpp + // + class gsv_text + { + enum status + { + initial, + next_char, + start_glyph, + glyph + }; + + public: + gsv_text(); + + void font(const void* font); + void flip(bool flip_y) { m_flip = flip_y; } + void load_font(const char* file); + void size(double height, double width=0.0); + void space(double space); + void line_space(double line_space); + void start_point(double x, double y); + void text(const char* text); + + double text_width(); + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + // not supposed to be copied + gsv_text(const gsv_text&); + const gsv_text& operator = (const gsv_text&); + + int16u value(const int8u* p) const + { + int16u v; + if(m_big_endian) + { + *(int8u*)&v = p[1]; + *((int8u*)&v + 1) = p[0]; + } + else + { + *(int8u*)&v = p[0]; + *((int8u*)&v + 1) = p[1]; + } + return v; + } + + private: + double m_x; + double m_y; + double m_start_x; + double m_width; + double m_height; + double m_space; + double m_line_space; + char m_chr[2]; + char* m_text; + pod_array<char> m_text_buf; + char* m_cur_chr; + const void* m_font; + pod_array<char> m_loaded_font; + status m_status; + bool m_big_endian; + bool m_flip; + int8u* m_indices; + int8* m_glyphs; + int8* m_bglyph; + int8* m_eglyph; + double m_w; + double m_h; + }; + + + + + //--------------------------------------------------------gsv_text_outline + template<class Transformer = trans_affine> class gsv_text_outline + { + public: + gsv_text_outline(gsv_text& text, Transformer& trans) : + m_polyline(text), + m_trans(m_polyline, trans) + { + } + + void width(double w) + { + m_polyline.width(w); + } + + void transformer(const Transformer* trans) + { + m_trans->transformer(trans); + } + + void rewind(unsigned path_id) + { + m_trans.rewind(path_id); + m_polyline.line_join(round_join); + m_polyline.line_cap(round_cap); + } + + unsigned vertex(double* x, double* y) + { + return m_trans.vertex(x, y); + } + + private: + conv_stroke<gsv_text> m_polyline; + conv_transform<conv_stroke<gsv_text>, Transformer> m_trans; + }; + + + +} + + +#endif diff --git a/include/agg_image_accessors.h b/include/agg_image_accessors.h new file mode 100644 index 0000000..c651d6d --- /dev/null +++ b/include/agg_image_accessors.h @@ -0,0 +1,481 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_IMAGE_ACCESSORS_INCLUDED +#define AGG_IMAGE_ACCESSORS_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //-----------------------------------------------------image_accessor_clip + template<class PixFmt> class image_accessor_clip + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::order_type order_type; + typedef typename pixfmt_type::value_type value_type; + enum pix_width_e { pix_width = pixfmt_type::pix_width }; + + image_accessor_clip() {} + explicit image_accessor_clip(pixfmt_type& pixf, + const color_type& bk) : + m_pixf(&pixf) + { + pixfmt_type::make_pix(m_bk_buf, bk); + } + + void attach(pixfmt_type& pixf) + { + m_pixf = &pixf; + } + + void background_color(const color_type& bk) + { + pixfmt_type::make_pix(m_bk_buf, bk); + } + + private: + AGG_INLINE const int8u* pixel() const + { + if(m_y >= 0 && m_y < (int)m_pixf->height() && + m_x >= 0 && m_x < (int)m_pixf->width()) + { + return m_pixf->pix_ptr(m_x, m_y); + } + return m_bk_buf; + } + + public: + AGG_INLINE const int8u* span(int x, int y, unsigned len) + { + m_x = m_x0 = x; + m_y = y; + if(y >= 0 && y < (int)m_pixf->height() && + x >= 0 && x+(int)len <= (int)m_pixf->width()) + { + return m_pix_ptr = m_pixf->pix_ptr(x, y); + } + m_pix_ptr = 0; + return pixel(); + } + + AGG_INLINE const int8u* next_x() + { + if(m_pix_ptr) return m_pix_ptr += pix_width; + ++m_x; + return pixel(); + } + + AGG_INLINE const int8u* next_y() + { + ++m_y; + m_x = m_x0; + if(m_pix_ptr && + m_y >= 0 && m_y < (int)m_pixf->height()) + { + return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y); + } + m_pix_ptr = 0; + return pixel(); + } + + private: + const pixfmt_type* m_pixf; + int8u m_bk_buf[pix_width]; + int m_x, m_x0, m_y; + const int8u* m_pix_ptr; + }; + + + + + //--------------------------------------------------image_accessor_no_clip + template<class PixFmt> class image_accessor_no_clip + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::order_type order_type; + typedef typename pixfmt_type::value_type value_type; + enum pix_width_e { pix_width = pixfmt_type::pix_width }; + + image_accessor_no_clip() {} + explicit image_accessor_no_clip(pixfmt_type& pixf) : + m_pixf(&pixf) + {} + + void attach(pixfmt_type& pixf) + { + m_pixf = &pixf; + } + + AGG_INLINE const int8u* span(int x, int y, unsigned) + { + m_x = x; + m_y = y; + return m_pix_ptr = m_pixf->pix_ptr(x, y); + } + + AGG_INLINE const int8u* next_x() + { + return m_pix_ptr += pix_width; + } + + AGG_INLINE const int8u* next_y() + { + ++m_y; + return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y); + } + + private: + const pixfmt_type* m_pixf; + int m_x, m_y; + const int8u* m_pix_ptr; + }; + + + + + //----------------------------------------------------image_accessor_clone + template<class PixFmt> class image_accessor_clone + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::order_type order_type; + typedef typename pixfmt_type::value_type value_type; + enum pix_width_e { pix_width = pixfmt_type::pix_width }; + + image_accessor_clone() {} + explicit image_accessor_clone(pixfmt_type& pixf) : + m_pixf(&pixf) + {} + + void attach(pixfmt_type& pixf) + { + m_pixf = &pixf; + } + + private: + AGG_INLINE const int8u* pixel() const + { + int x = m_x; + int y = m_y; + if(x < 0) x = 0; + if(y < 0) y = 0; + if(x >= (int)m_pixf->width()) x = m_pixf->width() - 1; + if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1; + return m_pixf->pix_ptr(x, y); + } + + public: + AGG_INLINE const int8u* span(int x, int y, unsigned len) + { + m_x = m_x0 = x; + m_y = y; + if(y >= 0 && y < (int)m_pixf->height() && + x >= 0 && x+len <= (int)m_pixf->width()) + { + return m_pix_ptr = m_pixf->pix_ptr(x, y); + } + m_pix_ptr = 0; + return pixel(); + } + + AGG_INLINE const int8u* next_x() + { + if(m_pix_ptr) return m_pix_ptr += pix_width; + ++m_x; + return pixel(); + } + + AGG_INLINE const int8u* next_y() + { + ++m_y; + m_x = m_x0; + if(m_pix_ptr && + m_y >= 0 && m_y < (int)m_pixf->height()) + { + return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y); + } + m_pix_ptr = 0; + return pixel(); + } + + private: + const pixfmt_type* m_pixf; + int m_x, m_x0, m_y; + const int8u* m_pix_ptr; + }; + + + + + + //-----------------------------------------------------image_accessor_wrap + template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::order_type order_type; + typedef typename pixfmt_type::value_type value_type; + enum pix_width_e { pix_width = pixfmt_type::pix_width }; + + image_accessor_wrap() {} + explicit image_accessor_wrap(pixfmt_type& pixf) : + m_pixf(&pixf), + m_wrap_x(pixf.width()), + m_wrap_y(pixf.height()) + {} + + void attach(pixfmt_type& pixf) + { + m_pixf = &pixf; + } + + AGG_INLINE const int8u* span(int x, int y, unsigned) + { + m_x = x; + m_row_ptr = m_pixf->pix_ptr(0, m_wrap_y(y)); + return m_row_ptr + m_wrap_x(x) * pix_width; + } + + AGG_INLINE const int8u* next_x() + { + int x = ++m_wrap_x; + return m_row_ptr + x * pix_width; + } + + AGG_INLINE const int8u* next_y() + { + m_row_ptr = m_pixf->pix_ptr(0, ++m_wrap_y); + return m_row_ptr + m_wrap_x(m_x) * pix_width; + } + + private: + const pixfmt_type* m_pixf; + const int8u* m_row_ptr; + int m_x; + WrapX m_wrap_x; + WrapY m_wrap_y; + }; + + + + + //--------------------------------------------------------wrap_mode_repeat + class wrap_mode_repeat + { + public: + wrap_mode_repeat() {} + wrap_mode_repeat(unsigned size) : + m_size(size), + m_add(size * (0x3FFFFFFF / size)), + m_value(0) + {} + + AGG_INLINE unsigned operator() (int v) + { + return m_value = (unsigned(v) + m_add) % m_size; + } + + AGG_INLINE unsigned operator++ () + { + ++m_value; + if(m_value >= m_size) m_value = 0; + return m_value; + } + private: + unsigned m_size; + unsigned m_add; + unsigned m_value; + }; + + + //---------------------------------------------------wrap_mode_repeat_pow2 + class wrap_mode_repeat_pow2 + { + public: + wrap_mode_repeat_pow2() {} + wrap_mode_repeat_pow2(unsigned size) : m_value(0) + { + m_mask = 1; + while(m_mask < size) m_mask = (m_mask << 1) | 1; + m_mask >>= 1; + } + AGG_INLINE unsigned operator() (int v) + { + return m_value = unsigned(v) & m_mask; + } + AGG_INLINE unsigned operator++ () + { + ++m_value; + if(m_value > m_mask) m_value = 0; + return m_value; + } + private: + unsigned m_mask; + unsigned m_value; + }; + + + //----------------------------------------------wrap_mode_repeat_auto_pow2 + class wrap_mode_repeat_auto_pow2 + { + public: + wrap_mode_repeat_auto_pow2() {} + wrap_mode_repeat_auto_pow2(unsigned size) : + m_size(size), + m_add(size * (0x3FFFFFFF / size)), + m_mask((m_size & (m_size-1)) ? 0 : m_size-1), + m_value(0) + {} + + AGG_INLINE unsigned operator() (int v) + { + if(m_mask) return m_value = unsigned(v) & m_mask; + return m_value = (unsigned(v) + m_add) % m_size; + } + AGG_INLINE unsigned operator++ () + { + ++m_value; + if(m_value >= m_size) m_value = 0; + return m_value; + } + + private: + unsigned m_size; + unsigned m_add; + unsigned m_mask; + unsigned m_value; + }; + + + //-------------------------------------------------------wrap_mode_reflect + class wrap_mode_reflect + { + public: + wrap_mode_reflect() {} + wrap_mode_reflect(unsigned size) : + m_size(size), + m_size2(size * 2), + m_add(m_size2 * (0x3FFFFFFF / m_size2)), + m_value(0) + {} + + AGG_INLINE unsigned operator() (int v) + { + m_value = (unsigned(v) + m_add) % m_size2; + if(m_value >= m_size) return m_size2 - m_value - 1; + return m_value; + } + + AGG_INLINE unsigned operator++ () + { + ++m_value; + if(m_value >= m_size2) m_value = 0; + if(m_value >= m_size) return m_size2 - m_value - 1; + return m_value; + } + private: + unsigned m_size; + unsigned m_size2; + unsigned m_add; + unsigned m_value; + }; + + + + //--------------------------------------------------wrap_mode_reflect_pow2 + class wrap_mode_reflect_pow2 + { + public: + wrap_mode_reflect_pow2() {} + wrap_mode_reflect_pow2(unsigned size) : m_value(0) + { + m_mask = 1; + m_size = 1; + while(m_mask < size) + { + m_mask = (m_mask << 1) | 1; + m_size <<= 1; + } + } + AGG_INLINE unsigned operator() (int v) + { + m_value = unsigned(v) & m_mask; + if(m_value >= m_size) return m_mask - m_value; + return m_value; + } + AGG_INLINE unsigned operator++ () + { + ++m_value; + m_value &= m_mask; + if(m_value >= m_size) return m_mask - m_value; + return m_value; + } + private: + unsigned m_size; + unsigned m_mask; + unsigned m_value; + }; + + + + //---------------------------------------------wrap_mode_reflect_auto_pow2 + class wrap_mode_reflect_auto_pow2 + { + public: + wrap_mode_reflect_auto_pow2() {} + wrap_mode_reflect_auto_pow2(unsigned size) : + m_size(size), + m_size2(size * 2), + m_add(m_size2 * (0x3FFFFFFF / m_size2)), + m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1), + m_value(0) + {} + + AGG_INLINE unsigned operator() (int v) + { + m_value = m_mask ? unsigned(v) & m_mask : + (unsigned(v) + m_add) % m_size2; + if(m_value >= m_size) return m_size2 - m_value - 1; + return m_value; + } + AGG_INLINE unsigned operator++ () + { + ++m_value; + if(m_value >= m_size2) m_value = 0; + if(m_value >= m_size) return m_size2 - m_value - 1; + return m_value; + } + + private: + unsigned m_size; + unsigned m_size2; + unsigned m_add; + unsigned m_mask; + unsigned m_value; + }; + + +} + + +#endif diff --git a/include/agg_image_filters.h b/include/agg_image_filters.h new file mode 100644 index 0000000..5199f51 --- /dev/null +++ b/include/agg_image_filters.h @@ -0,0 +1,449 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Image transformation filters, +// Filtering classes (image_filter_lut, image_filter), +// Basic filter shape classes +//---------------------------------------------------------------------------- +#ifndef AGG_IMAGE_FILTERS_INCLUDED +#define AGG_IMAGE_FILTERS_INCLUDED + +#include "agg_array.h" +#include "agg_math.h" + +namespace agg +{ + + // See Implementation agg_image_filters.cpp + + enum image_filter_scale_e + { + image_filter_shift = 14, //----image_filter_shift + image_filter_scale = 1 << image_filter_shift, //----image_filter_scale + image_filter_mask = image_filter_scale - 1 //----image_filter_mask + }; + + enum image_subpixel_scale_e + { + image_subpixel_shift = 8, //----image_subpixel_shift + image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale + image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask + }; + + + //-----------------------------------------------------image_filter_lut + class image_filter_lut + { + public: + template<class FilterF> void calculate(const FilterF& filter, + bool normalization=true) + { + filter; // prevent erroneous C4100 in MSVC + double r = filter.radius(); + realloc_lut(r); + unsigned i; + unsigned pivot = diameter() << (image_subpixel_shift - 1); + for(i = 0; i < pivot; i++) + { + double x = double(i) / double(image_subpixel_scale); + double y = filter.calc_weight(x); + m_weight_array[pivot + i] = + m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale); + } + unsigned end = (diameter() << image_subpixel_shift) - 1; + m_weight_array[0] = m_weight_array[end]; + if(normalization) + { + normalize(); + } + } + + image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {} + + template<class FilterF> image_filter_lut(const FilterF& filter, + bool normalization=true) + { + calculate(filter, normalization); + } + + double radius() const { return m_radius; } + unsigned diameter() const { return m_diameter; } + int start() const { return m_start; } + const int16* weight_array() const { return &m_weight_array[0]; } + void normalize(); + + private: + void realloc_lut(double radius); + image_filter_lut(const image_filter_lut&); + const image_filter_lut& operator = (const image_filter_lut&); + + double m_radius; + unsigned m_diameter; + int m_start; + pod_array<int16> m_weight_array; + }; + + + + //--------------------------------------------------------image_filter + template<class FilterF> class image_filter : public image_filter_lut + { + public: + image_filter() + { + calculate(m_filter_function); + } + private: + FilterF m_filter_function; + }; + + + //-----------------------------------------------image_filter_bilinear + struct image_filter_bilinear + { + static double radius() { return 1.0; } + static double calc_weight(double x) + { + return 1.0 - x; + } + }; + + + //-----------------------------------------------image_filter_hanning + struct image_filter_hanning + { + static double radius() { return 1.0; } + static double calc_weight(double x) + { + return 0.5 + 0.5 * std::cos(pi * x); + } + }; + + + //-----------------------------------------------image_filter_hamming + struct image_filter_hamming + { + static double radius() { return 1.0; } + static double calc_weight(double x) + { + return 0.54 + 0.46 * std::cos(pi * x); + } + }; + + //-----------------------------------------------image_filter_hermite + struct image_filter_hermite + { + static double radius() { return 1.0; } + static double calc_weight(double x) + { + return (2.0 * x - 3.0) * x * x + 1.0; + } + }; + + //------------------------------------------------image_filter_quadric + struct image_filter_quadric + { + static double radius() { return 1.5; } + static double calc_weight(double x) + { + double t; + if(x < 0.5) return 0.75 - x * x; + if(x < 1.5) {t = x - 1.5; return 0.5 * t * t;} + return 0.0; + } + }; + + //------------------------------------------------image_filter_bicubic + class image_filter_bicubic + { + static double pow3(double x) + { + return (x <= 0.0) ? 0.0 : x * x * x; + } + + public: + static double radius() { return 2.0; } + static double calc_weight(double x) + { + return + (1.0/6.0) * + (pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1)); + } + }; + + //-------------------------------------------------image_filter_kaiser + class image_filter_kaiser + { + double a; + double i0a; + double epsilon; + + public: + image_filter_kaiser(double b = 6.33) : + a(b), epsilon(1e-12) + { + i0a = 1.0 / bessel_i0(b); + } + + static double radius() { return 1.0; } + double calc_weight(double x) const + { + return bessel_i0(a * std::sqrt(1. - x * x)) * i0a; + } + + private: + double bessel_i0(double x) const + { + int i; + double sum, y, t; + + sum = 1.; + y = x * x / 4.; + t = y; + + for(i = 2; t > epsilon; i++) + { + sum += t; + t *= (double)y / (i * i); + } + return sum; + } + }; + + //----------------------------------------------image_filter_catrom + struct image_filter_catrom + { + static double radius() { return 2.0; } + static double calc_weight(double x) + { + if(x < 1.0) return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0)); + if(x < 2.0) return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x))); + return 0.; + } + }; + + //---------------------------------------------image_filter_mitchell + class image_filter_mitchell + { + double p0, p2, p3; + double q0, q1, q2, q3; + + public: + image_filter_mitchell(double b = 1.0/3.0, double c = 1.0/3.0) : + p0((6.0 - 2.0 * b) / 6.0), + p2((-18.0 + 12.0 * b + 6.0 * c) / 6.0), + p3((12.0 - 9.0 * b - 6.0 * c) / 6.0), + q0((8.0 * b + 24.0 * c) / 6.0), + q1((-12.0 * b - 48.0 * c) / 6.0), + q2((6.0 * b + 30.0 * c) / 6.0), + q3((-b - 6.0 * c) / 6.0) + {} + + static double radius() { return 2.0; } + double calc_weight(double x) const + { + if(x < 1.0) return p0 + x * x * (p2 + x * p3); + if(x < 2.0) return q0 + x * (q1 + x * (q2 + x * q3)); + return 0.0; + } + }; + + + //----------------------------------------------image_filter_spline16 + struct image_filter_spline16 + { + static double radius() { return 2.0; } + static double calc_weight(double x) + { + if(x < 1.0) + { + return ((x - 9.0/5.0 ) * x - 1.0/5.0 ) * x + 1.0; + } + return ((-1.0/3.0 * (x-1) + 4.0/5.0) * (x-1) - 7.0/15.0 ) * (x-1); + } + }; + + + //---------------------------------------------image_filter_spline36 + struct image_filter_spline36 + { + static double radius() { return 3.0; } + static double calc_weight(double x) + { + if(x < 1.0) + { + return ((13.0/11.0 * x - 453.0/209.0) * x - 3.0/209.0) * x + 1.0; + } + if(x < 2.0) + { + return ((-6.0/11.0 * (x-1) + 270.0/209.0) * (x-1) - 156.0/ 209.0) * (x-1); + } + return ((1.0/11.0 * (x-2) - 45.0/209.0) * (x-2) + 26.0/209.0) * (x-2); + } + }; + + + //----------------------------------------------image_filter_gaussian + struct image_filter_gaussian + { + static double radius() { return 2.0; } + static double calc_weight(double x) + { + return std::exp(-2.0 * x * x) * std::sqrt(2.0 / pi); + } + }; + + + //------------------------------------------------image_filter_bessel + struct image_filter_bessel + { + static double radius() { return 3.2383; } + static double calc_weight(double x) + { + return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x); + } + }; + + + //-------------------------------------------------image_filter_sinc + class image_filter_sinc + { + public: + image_filter_sinc(double r) : m_radius(r < 2.0 ? 2.0 : r) {} + double radius() const { return m_radius; } + double calc_weight(double x) const + { + if(x == 0.0) return 1.0; + x *= pi; + return std::sin(x) / x; + } + private: + double m_radius; + }; + + + //-----------------------------------------------image_filter_lanczos + class image_filter_lanczos + { + public: + image_filter_lanczos(double r) : m_radius(r < 2.0 ? 2.0 : r) {} + double radius() const { return m_radius; } + double calc_weight(double x) const + { + if(x == 0.0) return 1.0; + if(x > m_radius) return 0.0; + x *= pi; + double xr = x / m_radius; + return (std::sin(x) / x) * (std::sin(xr) / xr); + } + private: + double m_radius; + }; + + + //----------------------------------------------image_filter_blackman + class image_filter_blackman + { + public: + image_filter_blackman(double r) : m_radius(r < 2.0 ? 2.0 : r) {} + double radius() const { return m_radius; } + double calc_weight(double x) const + { + if(x == 0.0) return 1.0; + if(x > m_radius) return 0.0; + x *= pi; + double xr = x / m_radius; + return (std::sin(x) / x) * (0.42 + 0.5*std::cos(xr) + 0.08*std::cos(2*xr)); + } + private: + double m_radius; + }; + + //------------------------------------------------image_filter_sinc36 + class image_filter_sinc36 : public image_filter_sinc + { public: image_filter_sinc36() : image_filter_sinc(3.0){} }; + + //------------------------------------------------image_filter_sinc64 + class image_filter_sinc64 : public image_filter_sinc + { public: image_filter_sinc64() : image_filter_sinc(4.0){} }; + + //-----------------------------------------------image_filter_sinc100 + class image_filter_sinc100 : public image_filter_sinc + { public: image_filter_sinc100() : image_filter_sinc(5.0){} }; + + //-----------------------------------------------image_filter_sinc144 + class image_filter_sinc144 : public image_filter_sinc + { public: image_filter_sinc144() : image_filter_sinc(6.0){} }; + + //-----------------------------------------------image_filter_sinc196 + class image_filter_sinc196 : public image_filter_sinc + { public: image_filter_sinc196() : image_filter_sinc(7.0){} }; + + //-----------------------------------------------image_filter_sinc256 + class image_filter_sinc256 : public image_filter_sinc + { public: image_filter_sinc256() : image_filter_sinc(8.0){} }; + + //---------------------------------------------image_filter_lanczos36 + class image_filter_lanczos36 : public image_filter_lanczos + { public: image_filter_lanczos36() : image_filter_lanczos(3.0){} }; + + //---------------------------------------------image_filter_lanczos64 + class image_filter_lanczos64 : public image_filter_lanczos + { public: image_filter_lanczos64() : image_filter_lanczos(4.0){} }; + + //--------------------------------------------image_filter_lanczos100 + class image_filter_lanczos100 : public image_filter_lanczos + { public: image_filter_lanczos100() : image_filter_lanczos(5.0){} }; + + //--------------------------------------------image_filter_lanczos144 + class image_filter_lanczos144 : public image_filter_lanczos + { public: image_filter_lanczos144() : image_filter_lanczos(6.0){} }; + + //--------------------------------------------image_filter_lanczos196 + class image_filter_lanczos196 : public image_filter_lanczos + { public: image_filter_lanczos196() : image_filter_lanczos(7.0){} }; + + //--------------------------------------------image_filter_lanczos256 + class image_filter_lanczos256 : public image_filter_lanczos + { public: image_filter_lanczos256() : image_filter_lanczos(8.0){} }; + + //--------------------------------------------image_filter_blackman36 + class image_filter_blackman36 : public image_filter_blackman + { public: image_filter_blackman36() : image_filter_blackman(3.0){} }; + + //--------------------------------------------image_filter_blackman64 + class image_filter_blackman64 : public image_filter_blackman + { public: image_filter_blackman64() : image_filter_blackman(4.0){} }; + + //-------------------------------------------image_filter_blackman100 + class image_filter_blackman100 : public image_filter_blackman + { public: image_filter_blackman100() : image_filter_blackman(5.0){} }; + + //-------------------------------------------image_filter_blackman144 + class image_filter_blackman144 : public image_filter_blackman + { public: image_filter_blackman144() : image_filter_blackman(6.0){} }; + + //-------------------------------------------image_filter_blackman196 + class image_filter_blackman196 : public image_filter_blackman + { public: image_filter_blackman196() : image_filter_blackman(7.0){} }; + + //-------------------------------------------image_filter_blackman256 + class image_filter_blackman256 : public image_filter_blackman + { public: image_filter_blackman256() : image_filter_blackman(8.0){} }; + + +} + +#endif diff --git a/include/agg_line_aa_basics.h b/include/agg_line_aa_basics.h new file mode 100644 index 0000000..6726b9d --- /dev/null +++ b/include/agg_line_aa_basics.h @@ -0,0 +1,189 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_LINE_AA_BASICS_INCLUDED +#define AGG_LINE_AA_BASICS_INCLUDED + +#include <cstdlib> +#include "agg_basics.h" + +namespace agg +{ + + // See Implementation agg_line_aa_basics.cpp + + //------------------------------------------------------------------------- + enum line_subpixel_scale_e + { + line_subpixel_shift = 8, //----line_subpixel_shift + line_subpixel_scale = 1 << line_subpixel_shift, //----line_subpixel_scale + line_subpixel_mask = line_subpixel_scale - 1, //----line_subpixel_mask + line_max_coord = (1 << 28) - 1, //----line_max_coord + line_max_length = 1 << (line_subpixel_shift + 10) //----line_max_length + }; + + //------------------------------------------------------------------------- + enum line_mr_subpixel_scale_e + { + line_mr_subpixel_shift = 4, //----line_mr_subpixel_shift + line_mr_subpixel_scale = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_scale + line_mr_subpixel_mask = line_mr_subpixel_scale - 1 //----line_mr_subpixel_mask + }; + + //------------------------------------------------------------------line_mr + AGG_INLINE int line_mr(int x) + { + return x >> (line_subpixel_shift - line_mr_subpixel_shift); + } + + //-------------------------------------------------------------------line_hr + AGG_INLINE int line_hr(int x) + { + return x << (line_subpixel_shift - line_mr_subpixel_shift); + } + + //---------------------------------------------------------------line_dbl_hr + AGG_INLINE int line_dbl_hr(int x) + { + return x << line_subpixel_shift; + } + + //---------------------------------------------------------------line_coord + struct line_coord + { + AGG_INLINE static int conv(double x) + { + return iround(x * line_subpixel_scale); + } + }; + + //-----------------------------------------------------------line_coord_sat + struct line_coord_sat + { + AGG_INLINE static int conv(double x) + { + return saturation<line_max_coord>::iround(x * line_subpixel_scale); + } + }; + + //==========================================================line_parameters + struct line_parameters + { + //--------------------------------------------------------------------- + line_parameters() {} + line_parameters(int x1_, int y1_, int x2_, int y2_, int len_) : + x1(x1_), y1(y1_), x2(x2_), y2(y2_), + dx(std::abs(x2_ - x1_)), + dy(std::abs(y2_ - y1_)), + sx((x2_ > x1_) ? 1 : -1), + sy((y2_ > y1_) ? 1 : -1), + vertical(dy >= dx), + inc(vertical ? sy : sx), + len(len_), + octant((sy & 4) | (sx & 2) | int(vertical)) + { + } + + //--------------------------------------------------------------------- + unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; } + unsigned diagonal_quadrant() const { return s_diagonal_quadrant[octant]; } + + //--------------------------------------------------------------------- + bool same_orthogonal_quadrant(const line_parameters& lp) const + { + return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant]; + } + + //--------------------------------------------------------------------- + bool same_diagonal_quadrant(const line_parameters& lp) const + { + return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant]; + } + + //--------------------------------------------------------------------- + void divide(line_parameters& lp1, line_parameters& lp2) const + { + int xmid = (x1 + x2) >> 1; + int ymid = (y1 + y2) >> 1; + int len2 = len >> 1; + + lp1 = *this; + lp2 = *this; + + lp1.x2 = xmid; + lp1.y2 = ymid; + lp1.len = len2; + lp1.dx = std::abs(lp1.x2 - lp1.x1); + lp1.dy = std::abs(lp1.y2 - lp1.y1); + + lp2.x1 = xmid; + lp2.y1 = ymid; + lp2.len = len2; + lp2.dx = std::abs(lp2.x2 - lp2.x1); + lp2.dy = std::abs(lp2.y2 - lp2.y1); + } + + //--------------------------------------------------------------------- + int x1, y1, x2, y2, dx, dy, sx, sy; + bool vertical; + int inc; + int len; + int octant; + + //--------------------------------------------------------------------- + static const int8u s_orthogonal_quadrant[8]; + static const int8u s_diagonal_quadrant[8]; + }; + + + + // See Implementation agg_line_aa_basics.cpp + + //----------------------------------------------------------------bisectrix + void bisectrix(const line_parameters& l1, + const line_parameters& l2, + int* x, int* y); + + + //-------------------------------------------fix_degenerate_bisectrix_start + void inline fix_degenerate_bisectrix_start(const line_parameters& lp, + int* x, int* y) + { + int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - + double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len); + if(d < line_subpixel_scale/2) + { + *x = lp.x1 + (lp.y2 - lp.y1); + *y = lp.y1 - (lp.x2 - lp.x1); + } + } + + + //---------------------------------------------fix_degenerate_bisectrix_end + void inline fix_degenerate_bisectrix_end(const line_parameters& lp, + int* x, int* y) + { + int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) - + double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len); + if(d < line_subpixel_scale/2) + { + *x = lp.x2 + (lp.y2 - lp.y1); + *y = lp.y2 - (lp.x2 - lp.x1); + } + } + + +} + +#endif diff --git a/include/agg_math.h b/include/agg_math.h new file mode 100644 index 0000000..b3051bc --- /dev/null +++ b/include/agg_math.h @@ -0,0 +1,437 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// Bessel function (besj) was adapted for use in AGG library by Andy Wilk +// Contact: castor.vulgaris@gmail.com +//---------------------------------------------------------------------------- + +#ifndef AGG_MATH_INCLUDED +#define AGG_MATH_INCLUDED + +#include <cmath> +#include "agg_basics.h" + +namespace agg +{ + + //------------------------------------------------------vertex_dist_epsilon + // Coinciding points maximal distance (Epsilon) + const double vertex_dist_epsilon = 1e-14; + + //-----------------------------------------------------intersection_epsilon + // See calc_intersection + const double intersection_epsilon = 1.0e-30; + + //------------------------------------------------------------cross_product + AGG_INLINE double cross_product(double x1, double y1, + double x2, double y2, + double x, double y) + { + return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1); + } + + //--------------------------------------------------------point_in_triangle + AGG_INLINE bool point_in_triangle(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x, double y) + { + bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0; + bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0; + bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0; + return cp1 == cp2 && cp2 == cp3 && cp3 == cp1; + } + + //-----------------------------------------------------------calc_distance + AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2) + { + double dx = x2-x1; + double dy = y2-y1; + return std::sqrt(dx * dx + dy * dy); + } + + //--------------------------------------------------------calc_sq_distance + AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2) + { + double dx = x2-x1; + double dy = y2-y1; + return dx * dx + dy * dy; + } + + //------------------------------------------------calc_line_point_distance + AGG_INLINE double calc_line_point_distance(double x1, double y1, + double x2, double y2, + double x, double y) + { + double dx = x2-x1; + double dy = y2-y1; + double d = std::sqrt(dx * dx + dy * dy); + if(d < vertex_dist_epsilon) + { + return calc_distance(x1, y1, x, y); + } + return ((x - x2) * dy - (y - y2) * dx) / d; + } + + //-------------------------------------------------------calc_line_point_u + AGG_INLINE double calc_segment_point_u(double x1, double y1, + double x2, double y2, + double x, double y) + { + double dx = x2 - x1; + double dy = y2 - y1; + + if(dx == 0 && dy == 0) + { + return 0; + } + + double pdx = x - x1; + double pdy = y - y1; + + return (pdx * dx + pdy * dy) / (dx * dx + dy * dy); + } + + //---------------------------------------------calc_line_point_sq_distance + AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, + double x2, double y2, + double x, double y, + double u) + { + if(u <= 0) + { + return calc_sq_distance(x, y, x1, y1); + } + else + if(u >= 1) + { + return calc_sq_distance(x, y, x2, y2); + } + return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1)); + } + + //---------------------------------------------calc_line_point_sq_distance + AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, + double x2, double y2, + double x, double y) + { + return + calc_segment_point_sq_distance( + x1, y1, x2, y2, x, y, + calc_segment_point_u(x1, y1, x2, y2, x, y)); + } + + //-------------------------------------------------------calc_intersection + AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by, + double cx, double cy, double dx, double dy, + double* x, double* y) + { + double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy); + double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx); + if(std::fabs(den) < intersection_epsilon) return false; + double r = num / den; + *x = ax + r * (bx-ax); + *y = ay + r * (by-ay); + return true; + } + + //-----------------------------------------------------intersection_exists + AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2, + double x3, double y3, double x4, double y4) + { + // It's less expensive but you can't control the + // boundary conditions: Less or LessEqual + double dx1 = x2 - x1; + double dy1 = y2 - y1; + double dx2 = x4 - x3; + double dy2 = y4 - y3; + return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) != + ((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) && + ((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) != + ((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0); + + // It's is more expensive but more flexible + // in terms of boundary conditions. + //-------------------- + //double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3); + //if(fabs(den) < intersection_epsilon) return false; + //double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3); + //double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3); + //double ua = nom1 / den; + //double ub = nom2 / den; + //return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0; + } + + //--------------------------------------------------------calc_orthogonal + AGG_INLINE void calc_orthogonal(double thickness, + double x1, double y1, + double x2, double y2, + double* x, double* y) + { + double dx = x2 - x1; + double dy = y2 - y1; + double d = std::sqrt(dx*dx + dy*dy); + *x = thickness * dy / d; + *y = -thickness * dx / d; + } + + //--------------------------------------------------------dilate_triangle + AGG_INLINE void dilate_triangle(double x1, double y1, + double x2, double y2, + double x3, double y3, + double *x, double* y, + double d) + { + double dx1=0.0; + double dy1=0.0; + double dx2=0.0; + double dy2=0.0; + double dx3=0.0; + double dy3=0.0; + double loc = cross_product(x1, y1, x2, y2, x3, y3); + if(std::fabs(loc) > intersection_epsilon) + { + if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0) + { + d = -d; + } + calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1); + calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2); + calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3); + } + *x++ = x1 + dx1; *y++ = y1 + dy1; + *x++ = x2 + dx1; *y++ = y2 + dy1; + *x++ = x2 + dx2; *y++ = y2 + dy2; + *x++ = x3 + dx2; *y++ = y3 + dy2; + *x++ = x3 + dx3; *y++ = y3 + dy3; + *x++ = x1 + dx3; *y++ = y1 + dy3; + } + + //------------------------------------------------------calc_triangle_area + AGG_INLINE double calc_triangle_area(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5; + } + + //-------------------------------------------------------calc_polygon_area + template<class Storage> double calc_polygon_area(const Storage& st) + { + unsigned i; + double sum = 0.0; + double x = st[0].x; + double y = st[0].y; + double xs = x; + double ys = y; + + for(i = 1; i < st.size(); i++) + { + const typename Storage::value_type& v = st[i]; + sum += x * v.y - y * v.x; + x = v.x; + y = v.y; + } + return (sum + x * ys - y * xs) * 0.5; + } + + //------------------------------------------------------------------------ + // Tables for fast sqrt + extern int16u g_sqrt_table[1024]; + extern int8 g_elder_bit_table[256]; + + + //---------------------------------------------------------------fast_sqrt + //Fast integer Sqrt - really fast: no cycles, divisions or multiplications + #if defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable : 4035) //Disable warning "no return value" + #endif + AGG_INLINE unsigned fast_sqrt(unsigned val) + { + #if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM) + //For Ix86 family processors this assembler code is used. + //The key command here is bsr - determination the number of the most + //significant bit of the value. For other processors + //(and maybe compilers) the pure C "#else" section is used. + __asm + { + mov ebx, val + mov edx, 11 + bsr ecx, ebx + sub ecx, 9 + jle less_than_9_bits + shr ecx, 1 + adc ecx, 0 + sub edx, ecx + shl ecx, 1 + shr ebx, cl + less_than_9_bits: + xor eax, eax + mov ax, g_sqrt_table[ebx*2] + mov ecx, edx + shr eax, cl + } + #else + + //This code is actually pure C and portable to most + //arcitectures including 64bit ones. + unsigned t = val; + int bit=0; + unsigned shift = 11; + + //The following piece of code is just an emulation of the + //Ix86 assembler command "bsr" (see above). However on old + //Intels (like Intel MMX 233MHz) this code is about twice + //faster (sic!) then just one "bsr". On PIII and PIV the + //bsr is optimized quite well. + bit = t >> 24; + if(bit) + { + bit = g_elder_bit_table[bit] + 24; + } + else + { + bit = (t >> 16) & 0xFF; + if(bit) + { + bit = g_elder_bit_table[bit] + 16; + } + else + { + bit = (t >> 8) & 0xFF; + if(bit) + { + bit = g_elder_bit_table[bit] + 8; + } + else + { + bit = g_elder_bit_table[t]; + } + } + } + + //This code calculates the sqrt. + bit -= 9; + if(bit > 0) + { + bit = (bit >> 1) + (bit & 1); + shift -= bit; + val >>= (bit << 1); + } + return g_sqrt_table[val] >> shift; + #endif + } + #if defined(_MSC_VER) + #pragma warning(pop) + #endif + + + + + //--------------------------------------------------------------------besj + // Function BESJ calculates Bessel function of first kind of order n + // Arguments: + // n - an integer (>=0), the order + // x - value at which the Bessel function is required + //-------------------- + // C++ Mathematical Library + // Convereted from equivalent FORTRAN library + // Converetd by Gareth Walker for use by course 392 computational project + // All functions tested and yield the same results as the corresponding + // FORTRAN versions. + // + // If you have any problems using these functions please report them to + // M.Muldoon@UMIST.ac.uk + // + // Documentation available on the web + // http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html + // Version 1.0 8/98 + // 29 October, 1999 + //-------------------- + // Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com) + //------------------------------------------------------------------------ + inline double besj(double x, int n) + { + if(n < 0) + { + return 0; + } + double d = 1E-6; + double b = 0; + if(std::fabs(x) <= d) + { + if(n != 0) return 0; + return 1; + } + double b1 = 0; // b1 is the value from the previous iteration + // Set up a starting order for recurrence + int m1 = (int)std::fabs(x) + 6; + if(std::fabs(x) > 5) + { + m1 = (int)(std::fabs(1.4 * x + 60 / x)); + } + int m2 = (int)(n + 2 + std::fabs(x) / 4); + if (m1 > m2) + { + m2 = m1; + } + + // Apply recurrence down from curent max order + for(;;) + { + double c3 = 0; + double c2 = 1E-30; + double c4 = 0; + int m8 = 1; + if (m2 / 2 * 2 == m2) + { + m8 = -1; + } + int imax = m2 - 2; + for (int i = 1; i <= imax; i++) + { + double c6 = 2 * (m2 - i) * c2 / x - c3; + c3 = c2; + c2 = c6; + if(m2 - i - 1 == n) + { + b = c6; + } + m8 = -1 * m8; + if (m8 > 0) + { + c4 = c4 + 2 * c6; + } + } + double c6 = 2 * c2 / x - c3; + if(n == 0) + { + b = c6; + } + c4 += c6; + b /= c4; + if(std::fabs(b - b1) < d) + { + return b; + } + b1 = b; + m2 += 3; + } + } + +} + + +#endif diff --git a/include/agg_math_stroke.h b/include/agg_math_stroke.h new file mode 100644 index 0000000..b139711 --- /dev/null +++ b/include/agg_math_stroke.h @@ -0,0 +1,524 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Stroke math +// +//---------------------------------------------------------------------------- + +#ifndef AGG_STROKE_MATH_INCLUDED +#define AGG_STROKE_MATH_INCLUDED + +#include "agg_math.h" +#include "agg_vertex_sequence.h" + +namespace agg +{ + //-------------------------------------------------------------line_cap_e + enum line_cap_e + { + butt_cap, + square_cap, + round_cap + }; + + //------------------------------------------------------------line_join_e + enum line_join_e + { + miter_join = 0, + miter_join_revert = 1, + round_join = 2, + bevel_join = 3, + miter_join_round = 4 + }; + + + //-----------------------------------------------------------inner_join_e + enum inner_join_e + { + inner_bevel, + inner_miter, + inner_jag, + inner_round + }; + + //------------------------------------------------------------math_stroke + template<class VertexConsumer> class math_stroke + { + public: + typedef typename VertexConsumer::value_type coord_type; + + math_stroke(); + + void line_cap(line_cap_e lc) { m_line_cap = lc; } + void line_join(line_join_e lj) { m_line_join = lj; } + void inner_join(inner_join_e ij) { m_inner_join = ij; } + + line_cap_e line_cap() const { return m_line_cap; } + line_join_e line_join() const { return m_line_join; } + inner_join_e inner_join() const { return m_inner_join; } + + void width(double w); + void miter_limit(double ml) { m_miter_limit = ml; } + void miter_limit_theta(double t); + void inner_miter_limit(double ml) { m_inner_miter_limit = ml; } + void approximation_scale(double as) { m_approx_scale = as; } + + double width() const { return m_width * 2.0; } + double miter_limit() const { return m_miter_limit; } + double inner_miter_limit() const { return m_inner_miter_limit; } + double approximation_scale() const { return m_approx_scale; } + + void calc_cap(VertexConsumer& vc, + const vertex_dist& v0, + const vertex_dist& v1, + double len); + + void calc_join(VertexConsumer& vc, + const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + double len1, + double len2); + + private: + AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y) + { + vc.add(coord_type(x, y)); + } + + void calc_arc(VertexConsumer& vc, + double x, double y, + double dx1, double dy1, + double dx2, double dy2); + + void calc_miter(VertexConsumer& vc, + const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + double dx1, double dy1, + double dx2, double dy2, + line_join_e lj, + double mlimit, + double dbevel); + + double m_width; + double m_width_abs; + double m_width_eps; + int m_width_sign; + double m_miter_limit; + double m_inner_miter_limit; + double m_approx_scale; + line_cap_e m_line_cap; + line_join_e m_line_join; + inner_join_e m_inner_join; + }; + + //----------------------------------------------------------------------- + template<class VC> math_stroke<VC>::math_stroke() : + m_width(0.5), + m_width_abs(0.5), + m_width_eps(0.5/1024.0), + m_width_sign(1), + m_miter_limit(4.0), + m_inner_miter_limit(1.01), + m_approx_scale(1.0), + m_line_cap(butt_cap), + m_line_join(miter_join), + m_inner_join(inner_miter) + { + } + + //----------------------------------------------------------------------- + template<class VC> void math_stroke<VC>::width(double w) + { + m_width = w * 0.5; + if(m_width < 0) + { + m_width_abs = -m_width; + m_width_sign = -1; + } + else + { + m_width_abs = m_width; + m_width_sign = 1; + } + m_width_eps = m_width / 1024.0; + } + + //----------------------------------------------------------------------- + template<class VC> void math_stroke<VC>::miter_limit_theta(double t) + { + m_miter_limit = 1.0 / std::sin(t * 0.5) ; + } + + //----------------------------------------------------------------------- + template<class VC> + void math_stroke<VC>::calc_arc(VC& vc, + double x, double y, + double dx1, double dy1, + double dx2, double dy2) + { + double a1 = std::atan2(dy1 * m_width_sign, dx1 * m_width_sign); + double a2 = std::atan2(dy2 * m_width_sign, dx2 * m_width_sign); + double da = std::acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2; + int i, n; + + add_vertex(vc, x + dx1, y + dy1); + if(m_width_sign > 0) + { + if(a1 > a2) a2 += 2 * pi; + n = int((a2 - a1) / da); + da = (a2 - a1) / (n + 1); + a1 += da; + for(i = 0; i < n; i++) + { + add_vertex(vc, x + std::cos(a1) * m_width, y + std::sin(a1) * m_width); + a1 += da; + } + } + else + { + if(a1 < a2) a2 -= 2 * pi; + n = int((a1 - a2) / da); + da = (a1 - a2) / (n + 1); + a1 -= da; + for(i = 0; i < n; i++) + { + add_vertex(vc, x + std::cos(a1) * m_width, y + std::sin(a1) * m_width); + a1 -= da; + } + } + add_vertex(vc, x + dx2, y + dy2); + } + + //----------------------------------------------------------------------- + template<class VC> + void math_stroke<VC>::calc_miter(VC& vc, + const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + double dx1, double dy1, + double dx2, double dy2, + line_join_e lj, + double mlimit, + double dbevel) + { + double xi = v1.x; + double yi = v1.y; + double di = 1; + double lim = m_width_abs * mlimit; + bool miter_limit_exceeded = true; // Assume the worst + bool intersection_failed = true; // Assume the worst + + if(calc_intersection(v0.x + dx1, v0.y - dy1, + v1.x + dx1, v1.y - dy1, + v1.x + dx2, v1.y - dy2, + v2.x + dx2, v2.y - dy2, + &xi, &yi)) + { + // Calculation of the intersection succeeded + //--------------------- + di = calc_distance(v1.x, v1.y, xi, yi); + if(di <= lim) + { + // Inside the miter limit + //--------------------- + add_vertex(vc, xi, yi); + miter_limit_exceeded = false; + } + intersection_failed = false; + } + else + { + // Calculation of the intersection failed, most probably + // the three points lie one straight line. + // First check if v0 and v2 lie on the opposite sides of vector: + // (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular + // to the line determined by vertices v0 and v1. + // This condition determines whether the next line segments continues + // the previous one or goes back. + //---------------- + double x2 = v1.x + dx1; + double y2 = v1.y - dy1; + if((cross_product(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) == + (cross_product(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0)) + { + // This case means that the next segment continues + // the previous one (straight line) + //----------------- + add_vertex(vc, v1.x + dx1, v1.y - dy1); + miter_limit_exceeded = false; + } + } + + if(miter_limit_exceeded) + { + // Miter limit exceeded + //------------------------ + switch(lj) + { + case miter_join_revert: + // For the compatibility with SVG, PDF, etc, + // we use a simple bevel join instead of + // "smart" bevel + //------------------- + add_vertex(vc, v1.x + dx1, v1.y - dy1); + add_vertex(vc, v1.x + dx2, v1.y - dy2); + break; + + case miter_join_round: + calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2); + break; + + default: + // If no miter-revert, calculate new dx1, dy1, dx2, dy2 + //---------------- + if(intersection_failed) + { + mlimit *= m_width_sign; + add_vertex(vc, v1.x + dx1 + dy1 * mlimit, + v1.y - dy1 + dx1 * mlimit); + add_vertex(vc, v1.x + dx2 - dy2 * mlimit, + v1.y - dy2 - dx2 * mlimit); + } + else + { + double x1 = v1.x + dx1; + double y1 = v1.y - dy1; + double x2 = v1.x + dx2; + double y2 = v1.y - dy2; + di = (lim - dbevel) / (di - dbevel); + add_vertex(vc, x1 + (xi - x1) * di, + y1 + (yi - y1) * di); + add_vertex(vc, x2 + (xi - x2) * di, + y2 + (yi - y2) * di); + } + break; + } + } + } + + //--------------------------------------------------------stroke_calc_cap + template<class VC> + void math_stroke<VC>::calc_cap(VC& vc, + const vertex_dist& v0, + const vertex_dist& v1, + double len) + { + vc.remove_all(); + + double dx1 = (v1.y - v0.y) / len; + double dy1 = (v1.x - v0.x) / len; + double dx2 = 0; + double dy2 = 0; + + dx1 *= m_width; + dy1 *= m_width; + + if(m_line_cap != round_cap) + { + if(m_line_cap == square_cap) + { + dx2 = dy1 * m_width_sign; + dy2 = dx1 * m_width_sign; + } + add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2); + add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2); + } + else + { + double da = std::acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2; + double a1; + int i; + int n = int(pi / da); + + da = pi / (n + 1); + add_vertex(vc, v0.x - dx1, v0.y + dy1); + if(m_width_sign > 0) + { + a1 = std::atan2(dy1, -dx1); + a1 += da; + for(i = 0; i < n; i++) + { + add_vertex(vc, v0.x + std::cos(a1) * m_width, + v0.y + std::sin(a1) * m_width); + a1 += da; + } + } + else + { + a1 = std::atan2(-dy1, dx1); + a1 -= da; + for(i = 0; i < n; i++) + { + add_vertex(vc, v0.x + std::cos(a1) * m_width, + v0.y + std::sin(a1) * m_width); + a1 -= da; + } + } + add_vertex(vc, v0.x + dx1, v0.y - dy1); + } + } + + //----------------------------------------------------------------------- + template<class VC> + void math_stroke<VC>::calc_join(VC& vc, + const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + double len1, + double len2) + { + double dx1 = m_width * (v1.y - v0.y) / len1; + double dy1 = m_width * (v1.x - v0.x) / len1; + double dx2 = m_width * (v2.y - v1.y) / len2; + double dy2 = m_width * (v2.x - v1.x) / len2; + + vc.remove_all(); + + double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y); + if(cp != 0 && (cp > 0) == (m_width > 0)) + { + // Inner join + //--------------- + double limit = ((len1 < len2) ? len1 : len2) / m_width_abs; + if(limit < m_inner_miter_limit) + { + limit = m_inner_miter_limit; + } + + switch(m_inner_join) + { + default: // inner_bevel + add_vertex(vc, v1.x + dx1, v1.y - dy1); + add_vertex(vc, v1.x + dx2, v1.y - dy2); + break; + + case inner_miter: + calc_miter(vc, + v0, v1, v2, dx1, dy1, dx2, dy2, + miter_join_revert, + limit, 0); + break; + + case inner_jag: + case inner_round: + cp = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2); + if(cp < len1 * len1 && cp < len2 * len2) + { + calc_miter(vc, + v0, v1, v2, dx1, dy1, dx2, dy2, + miter_join_revert, + limit, 0); + } + else + { + if(m_inner_join == inner_jag) + { + add_vertex(vc, v1.x + dx1, v1.y - dy1); + add_vertex(vc, v1.x, v1.y ); + add_vertex(vc, v1.x + dx2, v1.y - dy2); + } + else + { + add_vertex(vc, v1.x + dx1, v1.y - dy1); + add_vertex(vc, v1.x, v1.y ); + calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1); + add_vertex(vc, v1.x, v1.y ); + add_vertex(vc, v1.x + dx2, v1.y - dy2); + } + } + break; + } + } + else + { + // Outer join + //--------------- + + // Calculate the distance between v1 and + // the central point of the bevel line segment + //--------------- + double dx = (dx1 + dx2) / 2; + double dy = (dy1 + dy2) / 2; + double dbevel = std::sqrt(dx * dx + dy * dy); + + if(m_line_join == round_join || m_line_join == bevel_join) + { + // This is an optimization that reduces the number of points + // in cases of almost collinear segments. If there's no + // visible difference between bevel and miter joins we'd rather + // use miter join because it adds only one point instead of two. + // + // Here we calculate the middle point between the bevel points + // and then, the distance between v1 and this middle point. + // At outer joins this distance always less than stroke width, + // because it's actually the height of an isosceles triangle of + // v1 and its two bevel points. If the difference between this + // width and this value is small (no visible bevel) we can + // add just one point. + // + // The constant in the expression makes the result approximately + // the same as in round joins and caps. You can safely comment + // out this entire "if". + //------------------- + if(m_approx_scale * (m_width_abs - dbevel) < m_width_eps) + { + if(calc_intersection(v0.x + dx1, v0.y - dy1, + v1.x + dx1, v1.y - dy1, + v1.x + dx2, v1.y - dy2, + v2.x + dx2, v2.y - dy2, + &dx, &dy)) + { + add_vertex(vc, dx, dy); + } + else + { + add_vertex(vc, v1.x + dx1, v1.y - dy1); + } + return; + } + } + + switch(m_line_join) + { + case miter_join: + case miter_join_revert: + case miter_join_round: + calc_miter(vc, + v0, v1, v2, dx1, dy1, dx2, dy2, + m_line_join, + m_miter_limit, + dbevel); + break; + + case round_join: + calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2); + break; + + default: // Bevel join + add_vertex(vc, v1.x + dx1, v1.y - dy1); + add_vertex(vc, v1.x + dx2, v1.y - dy2); + break; + } + } + } + + + + +} + +#endif diff --git a/include/agg_path_length.h b/include/agg_path_length.h new file mode 100644 index 0000000..740ba31 --- /dev/null +++ b/include/agg_path_length.h @@ -0,0 +1,65 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_PATH_LENGTH_INCLUDED +#define AGG_PATH_LENGTH_INCLUDED + +#include "agg_math.h" + +namespace agg +{ + template<class VertexSource> + double path_length(VertexSource& vs, unsigned path_id = 0) + { + double len = 0.0; + double start_x = 0.0; + double start_y = 0.0; + double x1 = 0.0; + double y1 = 0.0; + double x2 = 0.0; + double y2 = 0.0; + bool first = true; + + unsigned cmd; + vs.rewind(path_id); + while(!is_stop(cmd = vs.vertex(&x2, &y2))) + { + if(is_vertex(cmd)) + { + if(first || is_move_to(cmd)) + { + start_x = x2; + start_y = y2; + } + else + { + len += calc_distance(x1, y1, x2, y2); + } + x1 = x2; + y1 = y2; + first = false; + } + else + { + if(is_close(cmd) && !first) + { + len += calc_distance(x1, y1, start_x, start_y); + } + } + } + return len; + } +} + +#endif diff --git a/include/agg_path_storage.h b/include/agg_path_storage.h new file mode 100644 index 0000000..3a62f71 --- /dev/null +++ b/include/agg_path_storage.h @@ -0,0 +1,1581 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_PATH_STORAGE_INCLUDED +#define AGG_PATH_STORAGE_INCLUDED + +#include <cstring> +#include "agg_math.h" +#include "agg_array.h" +#include "agg_bezier_arc.h" + +namespace agg +{ + + + //----------------------------------------------------vertex_block_storage + template<class T, unsigned BlockShift=8, unsigned BlockPool=256> + class vertex_block_storage + { + public: + // Allocation parameters + enum block_scale_e + { + block_shift = BlockShift, + block_size = 1 << block_shift, + block_mask = block_size - 1, + block_pool = BlockPool + }; + + typedef T value_type; + typedef vertex_block_storage<T, BlockShift, BlockPool> self_type; + + ~vertex_block_storage(); + vertex_block_storage(); + vertex_block_storage(const self_type& v); + const self_type& operator = (const self_type& ps); + + void remove_all(); + void free_all(); + + void add_vertex(double x, double y, unsigned cmd); + void modify_vertex(unsigned idx, double x, double y); + void modify_vertex(unsigned idx, double x, double y, unsigned cmd); + void modify_command(unsigned idx, unsigned cmd); + void swap_vertices(unsigned v1, unsigned v2); + + unsigned last_command() const; + unsigned last_vertex(double* x, double* y) const; + unsigned prev_vertex(double* x, double* y) const; + + double last_x() const; + double last_y() const; + + unsigned total_vertices() const; + unsigned vertex(unsigned idx, double* x, double* y) const; + unsigned command(unsigned idx) const; + + private: + void allocate_block(unsigned nb); + int8u* storage_ptrs(T** xy_ptr); + + private: + unsigned m_total_vertices; + unsigned m_total_blocks; + unsigned m_max_blocks; + T** m_coord_blocks; + int8u** m_cmd_blocks; + }; + + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + void vertex_block_storage<T,S,P>::free_all() + { + if(m_total_blocks) + { + T** coord_blk = m_coord_blocks + m_total_blocks - 1; + while(m_total_blocks--) + { + pod_allocator<T>::deallocate( + *coord_blk, + block_size * 2 + + block_size / (sizeof(T) / sizeof(unsigned char))); + --coord_blk; + } + pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2); + m_total_blocks = 0; + m_max_blocks = 0; + m_coord_blocks = 0; + m_cmd_blocks = 0; + m_total_vertices = 0; + } + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + vertex_block_storage<T,S,P>::~vertex_block_storage() + { + free_all(); + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + vertex_block_storage<T,S,P>::vertex_block_storage() : + m_total_vertices(0), + m_total_blocks(0), + m_max_blocks(0), + m_coord_blocks(0), + m_cmd_blocks(0) + { + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + vertex_block_storage<T,S,P>::vertex_block_storage(const vertex_block_storage<T,S,P>& v) : + m_total_vertices(0), + m_total_blocks(0), + m_max_blocks(0), + m_coord_blocks(0), + m_cmd_blocks(0) + { + *this = v; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + const vertex_block_storage<T,S,P>& + vertex_block_storage<T,S,P>::operator = (const vertex_block_storage<T,S,P>& v) + { + remove_all(); + unsigned i; + for(i = 0; i < v.total_vertices(); i++) + { + double x, y; + unsigned cmd = v.vertex(i, &x, &y); + add_vertex(x, y, cmd); + } + return *this; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::remove_all() + { + m_total_vertices = 0; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::add_vertex(double x, double y, + unsigned cmd) + { + T* coord_ptr = 0; + *storage_ptrs(&coord_ptr) = (int8u)cmd; + coord_ptr[0] = T(x); + coord_ptr[1] = T(y); + m_total_vertices++; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx, + double x, double y) + { + T* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1); + pv[0] = T(x); + pv[1] = T(y); + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx, + double x, double y, + unsigned cmd) + { + unsigned block = idx >> block_shift; + unsigned offset = idx & block_mask; + T* pv = m_coord_blocks[block] + (offset << 1); + pv[0] = T(x); + pv[1] = T(y); + m_cmd_blocks[block][offset] = (int8u)cmd; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::modify_command(unsigned idx, + unsigned cmd) + { + m_cmd_blocks[idx >> block_shift][idx & block_mask] = (int8u)cmd; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::swap_vertices(unsigned v1, unsigned v2) + { + unsigned b1 = v1 >> block_shift; + unsigned b2 = v2 >> block_shift; + unsigned o1 = v1 & block_mask; + unsigned o2 = v2 & block_mask; + T* pv1 = m_coord_blocks[b1] + (o1 << 1); + T* pv2 = m_coord_blocks[b2] + (o2 << 1); + T val; + val = pv1[0]; pv1[0] = pv2[0]; pv2[0] = val; + val = pv1[1]; pv1[1] = pv2[1]; pv2[1] = val; + int8u cmd = m_cmd_blocks[b1][o1]; + m_cmd_blocks[b1][o1] = m_cmd_blocks[b2][o2]; + m_cmd_blocks[b2][o2] = cmd; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::last_command() const + { + if(m_total_vertices) return command(m_total_vertices - 1); + return path_cmd_stop; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::last_vertex(double* x, double* y) const + { + if(m_total_vertices) return vertex(m_total_vertices - 1, x, y); + return path_cmd_stop; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::prev_vertex(double* x, double* y) const + { + if(m_total_vertices > 1) return vertex(m_total_vertices - 2, x, y); + return path_cmd_stop; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline double vertex_block_storage<T,S,P>::last_x() const + { + if(m_total_vertices) + { + unsigned idx = m_total_vertices - 1; + return m_coord_blocks[idx >> block_shift][(idx & block_mask) << 1]; + } + return 0.0; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline double vertex_block_storage<T,S,P>::last_y() const + { + if(m_total_vertices) + { + unsigned idx = m_total_vertices - 1; + return m_coord_blocks[idx >> block_shift][((idx & block_mask) << 1) + 1]; + } + return 0.0; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::total_vertices() const + { + return m_total_vertices; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::vertex(unsigned idx, + double* x, double* y) const + { + unsigned nb = idx >> block_shift; + const T* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1); + *x = pv[0]; + *y = pv[1]; + return m_cmd_blocks[nb][idx & block_mask]; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::command(unsigned idx) const + { + return m_cmd_blocks[idx >> block_shift][idx & block_mask]; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + void vertex_block_storage<T,S,P>::allocate_block(unsigned nb) + { + if(nb >= m_max_blocks) + { + T** new_coords = + pod_allocator<T*>::allocate((m_max_blocks + block_pool) * 2); + + unsigned char** new_cmds = + (unsigned char**)(new_coords + m_max_blocks + block_pool); + + if(m_coord_blocks) + { + std::memcpy(new_coords, + m_coord_blocks, + m_max_blocks * sizeof(T*)); + + std::memcpy(new_cmds, + m_cmd_blocks, + m_max_blocks * sizeof(unsigned char*)); + + pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2); + } + m_coord_blocks = new_coords; + m_cmd_blocks = new_cmds; + m_max_blocks += block_pool; + } + m_coord_blocks[nb] = + pod_allocator<T>::allocate(block_size * 2 + + block_size / (sizeof(T) / sizeof(unsigned char))); + + m_cmd_blocks[nb] = + (unsigned char*)(m_coord_blocks[nb] + block_size * 2); + + m_total_blocks++; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + int8u* vertex_block_storage<T,S,P>::storage_ptrs(T** xy_ptr) + { + unsigned nb = m_total_vertices >> block_shift; + if(nb >= m_total_blocks) + { + allocate_block(nb); + } + *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1); + return m_cmd_blocks[nb] + (m_total_vertices & block_mask); + } + + + + + //-----------------------------------------------------poly_plain_adaptor + template<class T> class poly_plain_adaptor + { + public: + typedef T value_type; + + poly_plain_adaptor() : + m_data(0), + m_ptr(0), + m_end(0), + m_closed(false), + m_stop(false) + {} + + poly_plain_adaptor(const T* data, unsigned num_points, bool closed) : + m_data(data), + m_ptr(data), + m_end(data + num_points * 2), + m_closed(closed), + m_stop(false) + {} + + void init(const T* data, unsigned num_points, bool closed) + { + m_data = data; + m_ptr = data; + m_end = data + num_points * 2; + m_closed = closed; + m_stop = false; + } + + void rewind(unsigned) + { + m_ptr = m_data; + m_stop = false; + } + + unsigned vertex(double* x, double* y) + { + if(m_ptr < m_end) + { + bool first = m_ptr == m_data; + *x = *m_ptr++; + *y = *m_ptr++; + return first ? path_cmd_move_to : path_cmd_line_to; + } + *x = *y = 0.0; + if(m_closed && !m_stop) + { + m_stop = true; + return path_cmd_end_poly | path_flags_close; + } + return path_cmd_stop; + } + + private: + const T* m_data; + const T* m_ptr; + const T* m_end; + bool m_closed; + bool m_stop; + }; + + + + + + //-------------------------------------------------poly_container_adaptor + template<class Container> class poly_container_adaptor + { + public: + typedef typename Container::value_type vertex_type; + + poly_container_adaptor() : + m_container(0), + m_index(0), + m_closed(false), + m_stop(false) + {} + + poly_container_adaptor(const Container& data, bool closed) : + m_container(&data), + m_index(0), + m_closed(closed), + m_stop(false) + {} + + void init(const Container& data, bool closed) + { + m_container = &data; + m_index = 0; + m_closed = closed; + m_stop = false; + } + + void rewind(unsigned) + { + m_index = 0; + m_stop = false; + } + + unsigned vertex(double* x, double* y) + { + if(m_index < m_container->size()) + { + bool first = m_index == 0; + const vertex_type& v = (*m_container)[m_index++]; + *x = v.x; + *y = v.y; + return first ? path_cmd_move_to : path_cmd_line_to; + } + *x = *y = 0.0; + if(m_closed && !m_stop) + { + m_stop = true; + return path_cmd_end_poly | path_flags_close; + } + return path_cmd_stop; + } + + private: + const Container* m_container; + unsigned m_index; + bool m_closed; + bool m_stop; + }; + + + + //-----------------------------------------poly_container_reverse_adaptor + template<class Container> class poly_container_reverse_adaptor + { + public: + typedef typename Container::value_type vertex_type; + + poly_container_reverse_adaptor() : + m_container(0), + m_index(-1), + m_closed(false), + m_stop(false) + {} + + poly_container_reverse_adaptor(Container& data, bool closed) : + m_container(&data), + m_index(-1), + m_closed(closed), + m_stop(false) + {} + + void init(Container& data, bool closed) + { + m_container = &data; + m_index = m_container->size() - 1; + m_closed = closed; + m_stop = false; + } + + void rewind(unsigned) + { + m_index = m_container->size() - 1; + m_stop = false; + } + + unsigned vertex(double* x, double* y) + { + if(m_index >= 0) + { + bool first = m_index == int(m_container->size() - 1); + const vertex_type& v = (*m_container)[m_index--]; + *x = v.x; + *y = v.y; + return first ? path_cmd_move_to : path_cmd_line_to; + } + *x = *y = 0.0; + if(m_closed && !m_stop) + { + m_stop = true; + return path_cmd_end_poly | path_flags_close; + } + return path_cmd_stop; + } + + private: + Container* m_container; + int m_index; + bool m_closed; + bool m_stop; + }; + + + + + + //--------------------------------------------------------line_adaptor + class line_adaptor + { + public: + typedef double value_type; + + line_adaptor() : m_line(m_coord, 2, false) {} + line_adaptor(double x1, double y1, double x2, double y2) : + m_line(m_coord, 2, false) + { + m_coord[0] = x1; + m_coord[1] = y1; + m_coord[2] = x2; + m_coord[3] = y2; + } + + void init(double x1, double y1, double x2, double y2) + { + m_coord[0] = x1; + m_coord[1] = y1; + m_coord[2] = x2; + m_coord[3] = y2; + m_line.rewind(0); + } + + void rewind(unsigned) + { + m_line.rewind(0); + } + + unsigned vertex(double* x, double* y) + { + return m_line.vertex(x, y); + } + + private: + double m_coord[4]; + poly_plain_adaptor<double> m_line; + }; + + + + + + + + + + + + + + //---------------------------------------------------------------path_base + // A container to store vertices with their flags. + // A path consists of a number of contours separated with "move_to" + // commands. The path storage can keep and maintain more than one + // path. + // To navigate to the beginning of a particular path, use rewind(path_id); + // Where path_id is what start_new_path() returns. So, when you call + // start_new_path() you need to store its return value somewhere else + // to navigate to the path afterwards. + // + // See also: vertex_source concept + //------------------------------------------------------------------------ + template<class VertexContainer> class path_base + { + public: + typedef VertexContainer container_type; + typedef path_base<VertexContainer> self_type; + + //-------------------------------------------------------------------- + path_base() : m_vertices(), m_iterator(0) {} + void remove_all() { m_vertices.remove_all(); m_iterator = 0; } + void free_all() { m_vertices.free_all(); m_iterator = 0; } + + // Make path functions + //-------------------------------------------------------------------- + unsigned start_new_path(); + + void move_to(double x, double y); + void move_rel(double dx, double dy); + + void line_to(double x, double y); + void line_rel(double dx, double dy); + + void hline_to(double x); + void hline_rel(double dx); + + void vline_to(double y); + void vline_rel(double dy); + + void arc_to(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x, double y); + + void arc_rel(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double dx, double dy); + + void curve3(double x_ctrl, double y_ctrl, + double x_to, double y_to); + + void curve3_rel(double dx_ctrl, double dy_ctrl, + double dx_to, double dy_to); + + void curve3(double x_to, double y_to); + + void curve3_rel(double dx_to, double dy_to); + + void curve4(double x_ctrl1, double y_ctrl1, + double x_ctrl2, double y_ctrl2, + double x_to, double y_to); + + void curve4_rel(double dx_ctrl1, double dy_ctrl1, + double dx_ctrl2, double dy_ctrl2, + double dx_to, double dy_to); + + void curve4(double x_ctrl2, double y_ctrl2, + double x_to, double y_to); + + void curve4_rel(double x_ctrl2, double y_ctrl2, + double x_to, double y_to); + + + void end_poly(unsigned flags = path_flags_close); + void close_polygon(unsigned flags = path_flags_none); + + // Accessors + //-------------------------------------------------------------------- + const container_type& vertices() const { return m_vertices; } + container_type& vertices() { return m_vertices; } + + unsigned total_vertices() const; + + void rel_to_abs(double* x, double* y) const; + + unsigned last_vertex(double* x, double* y) const; + unsigned prev_vertex(double* x, double* y) const; + + double last_x() const; + double last_y() const; + + unsigned vertex(unsigned idx, double* x, double* y) const; + unsigned command(unsigned idx) const; + + void modify_vertex(unsigned idx, double x, double y); + void modify_vertex(unsigned idx, double x, double y, unsigned cmd); + void modify_command(unsigned idx, unsigned cmd); + + // VertexSource interface + //-------------------------------------------------------------------- + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + // Arrange the orientation of a polygon, all polygons in a path, + // or in all paths. After calling arrange_orientations() or + // arrange_orientations_all_paths(), all the polygons will have + // the same orientation, i.e. path_flags_cw or path_flags_ccw + //-------------------------------------------------------------------- + unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation); + unsigned arrange_orientations(unsigned path_id, path_flags_e orientation); + void arrange_orientations_all_paths(path_flags_e orientation); + void invert_polygon(unsigned start); + + // Flip all vertices horizontally or vertically, + // between x1 and x2, or between y1 and y2 respectively + //-------------------------------------------------------------------- + void flip_x(double x1, double x2); + void flip_y(double y1, double y2); + + // Concatenate path. The path is added as is. + //-------------------------------------------------------------------- + template<class VertexSource> + void concat_path(VertexSource& vs, unsigned path_id = 0) + { + double x, y; + unsigned cmd; + vs.rewind(path_id); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + m_vertices.add_vertex(x, y, cmd); + } + } + + //-------------------------------------------------------------------- + // Join path. The path is joined with the existing one, that is, + // it behaves as if the pen of a plotter was always down (drawing) + template<class VertexSource> + void join_path(VertexSource& vs, unsigned path_id = 0) + { + double x, y; + unsigned cmd; + vs.rewind(path_id); + cmd = vs.vertex(&x, &y); + if(!is_stop(cmd)) + { + if(is_vertex(cmd)) + { + double x0, y0; + unsigned cmd0 = last_vertex(&x0, &y0); + if(is_vertex(cmd0)) + { + if(calc_distance(x, y, x0, y0) > vertex_dist_epsilon) + { + if(is_move_to(cmd)) cmd = path_cmd_line_to; + m_vertices.add_vertex(x, y, cmd); + } + } + else + { + if(is_stop(cmd0)) + { + cmd = path_cmd_move_to; + } + else + { + if(is_move_to(cmd)) cmd = path_cmd_line_to; + } + m_vertices.add_vertex(x, y, cmd); + } + } + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + m_vertices.add_vertex(x, y, is_move_to(cmd) ? + unsigned(path_cmd_line_to) : + cmd); + } + } + } + + // Concatenate polygon/polyline. + //-------------------------------------------------------------------- + template<class T> void concat_poly(const T* data, + unsigned num_points, + bool closed) + { + poly_plain_adaptor<T> poly(data, num_points, closed); + concat_path(poly); + } + + // Join polygon/polyline continuously. + //-------------------------------------------------------------------- + template<class T> void join_poly(const T* data, + unsigned num_points, + bool closed) + { + poly_plain_adaptor<T> poly(data, num_points, closed); + join_path(poly); + } + + //-------------------------------------------------------------------- + void translate(double dx, double dy, unsigned path_id=0); + void translate_all_paths(double dx, double dy); + + //-------------------------------------------------------------------- + template<class Trans> + void transform(const Trans& trans, unsigned path_id=0) + { + unsigned num_ver = m_vertices.total_vertices(); + for(; path_id < num_ver; path_id++) + { + double x, y; + unsigned cmd = m_vertices.vertex(path_id, &x, &y); + if(is_stop(cmd)) break; + if(is_vertex(cmd)) + { + trans.transform(&x, &y); + m_vertices.modify_vertex(path_id, x, y); + } + } + } + + //-------------------------------------------------------------------- + template<class Trans> + void transform_all_paths(const Trans& trans) + { + unsigned idx; + unsigned num_ver = m_vertices.total_vertices(); + for(idx = 0; idx < num_ver; idx++) + { + double x, y; + if(is_vertex(m_vertices.vertex(idx, &x, &y))) + { + trans.transform(&x, &y); + m_vertices.modify_vertex(idx, x, y); + } + } + } + + + //-------------------------------------------------------------------- + // If the end points of a path are very, very close then make them + // exactly equal so that the stroke converter is not confused. + //-------------------------------------------------------------------- + unsigned align_path(unsigned idx = 0) + { + if (idx >= total_vertices() || !is_move_to(command(idx))) + { + return total_vertices(); + } + + double start_x, start_y; + for (; idx < total_vertices() && is_move_to(command(idx)); ++idx) + { + vertex(idx, &start_x, &start_y); + } + while (idx < total_vertices() && is_drawing(command(idx))) + ++idx; + + double x, y; + if (is_drawing(vertex(idx - 1, &x, &y)) && + is_equal_eps(x, start_x, 1e-8) && + is_equal_eps(y, start_y, 1e-8)) + { + modify_vertex(idx - 1, start_x, start_y); + } + + while (idx < total_vertices() && !is_move_to(command(idx))) + ++idx; + return idx; + } + + void align_all_paths() + { + for (unsigned i = 0; i < total_vertices(); i = align_path(i)); + } + + + private: + unsigned perceive_polygon_orientation(unsigned start, unsigned end); + void invert_polygon(unsigned start, unsigned end); + + VertexContainer m_vertices; + unsigned m_iterator; + }; + + //------------------------------------------------------------------------ + template<class VC> + unsigned path_base<VC>::start_new_path() + { + if(!is_stop(m_vertices.last_command())) + { + m_vertices.add_vertex(0.0, 0.0, path_cmd_stop); + } + return m_vertices.total_vertices(); + } + + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::rel_to_abs(double* x, double* y) const + { + if(m_vertices.total_vertices()) + { + double x2; + double y2; + if(is_vertex(m_vertices.last_vertex(&x2, &y2))) + { + *x += x2; + *y += y2; + } + } + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::move_to(double x, double y) + { + m_vertices.add_vertex(x, y, path_cmd_move_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::move_rel(double dx, double dy) + { + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_move_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::line_to(double x, double y) + { + m_vertices.add_vertex(x, y, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::line_rel(double dx, double dy) + { + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::hline_to(double x) + { + m_vertices.add_vertex(x, last_y(), path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::hline_rel(double dx) + { + double dy = 0; + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::vline_to(double y) + { + m_vertices.add_vertex(last_x(), y, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::vline_rel(double dy) + { + double dx = 0; + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::arc_to(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x, double y) + { + if(m_vertices.total_vertices() && is_vertex(m_vertices.last_command())) + { + const double epsilon = 1e-30; + double x0 = 0.0; + double y0 = 0.0; + m_vertices.last_vertex(&x0, &y0); + + rx = std::fabs(rx); + ry = std::fabs(ry); + + // Ensure radii are valid + //------------------------- + if(rx < epsilon || ry < epsilon) + { + line_to(x, y); + return; + } + + if(calc_distance(x0, y0, x, y) < epsilon) + { + // If the endpoints (x, y) and (x0, y0) are identical, then this + // is equivalent to omitting the elliptical arc segment entirely. + return; + } + bezier_arc_svg a(x0, y0, rx, ry, angle, large_arc_flag, sweep_flag, x, y); + if(a.radii_ok()) + { + join_path(a); + } + else + { + line_to(x, y); + } + } + else + { + move_to(x, y); + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::arc_rel(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double dx, double dy) + { + rel_to_abs(&dx, &dy); + arc_to(rx, ry, angle, large_arc_flag, sweep_flag, dx, dy); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve3(double x_ctrl, double y_ctrl, + double x_to, double y_to) + { + m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3); + m_vertices.add_vertex(x_to, y_to, path_cmd_curve3); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve3_rel(double dx_ctrl, double dy_ctrl, + double dx_to, double dy_to) + { + rel_to_abs(&dx_ctrl, &dy_ctrl); + rel_to_abs(&dx_to, &dy_to); + m_vertices.add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3); + m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve3); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve3(double x_to, double y_to) + { + double x0; + double y0; + if(is_vertex(m_vertices.last_vertex(&x0, &y0))) + { + double x_ctrl; + double y_ctrl; + unsigned cmd = m_vertices.prev_vertex(&x_ctrl, &y_ctrl); + if(is_curve(cmd)) + { + x_ctrl = x0 + x0 - x_ctrl; + y_ctrl = y0 + y0 - y_ctrl; + } + else + { + x_ctrl = x0; + y_ctrl = y0; + } + curve3(x_ctrl, y_ctrl, x_to, y_to); + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve3_rel(double dx_to, double dy_to) + { + rel_to_abs(&dx_to, &dy_to); + curve3(dx_to, dy_to); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve4(double x_ctrl1, double y_ctrl1, + double x_ctrl2, double y_ctrl2, + double x_to, double y_to) + { + m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4); + m_vertices.add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4); + m_vertices.add_vertex(x_to, y_to, path_cmd_curve4); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve4_rel(double dx_ctrl1, double dy_ctrl1, + double dx_ctrl2, double dy_ctrl2, + double dx_to, double dy_to) + { + rel_to_abs(&dx_ctrl1, &dy_ctrl1); + rel_to_abs(&dx_ctrl2, &dy_ctrl2); + rel_to_abs(&dx_to, &dy_to); + m_vertices.add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4); + m_vertices.add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4); + m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve4); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve4(double x_ctrl2, double y_ctrl2, + double x_to, double y_to) + { + double x0; + double y0; + if(is_vertex(last_vertex(&x0, &y0))) + { + double x_ctrl1; + double y_ctrl1; + unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1); + if(is_curve(cmd)) + { + x_ctrl1 = x0 + x0 - x_ctrl1; + y_ctrl1 = y0 + y0 - y_ctrl1; + } + else + { + x_ctrl1 = x0; + y_ctrl1 = y0; + } + curve4(x_ctrl1, y_ctrl1, x_ctrl2, y_ctrl2, x_to, y_to); + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve4_rel(double dx_ctrl2, double dy_ctrl2, + double dx_to, double dy_to) + { + rel_to_abs(&dx_ctrl2, &dy_ctrl2); + rel_to_abs(&dx_to, &dy_to); + curve4(dx_ctrl2, dy_ctrl2, dx_to, dy_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::end_poly(unsigned flags) + { + if(is_vertex(m_vertices.last_command())) + { + m_vertices.add_vertex(0.0, 0.0, path_cmd_end_poly | flags); + } + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::close_polygon(unsigned flags) + { + end_poly(path_flags_close | flags); + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::total_vertices() const + { + return m_vertices.total_vertices(); + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::last_vertex(double* x, double* y) const + { + return m_vertices.last_vertex(x, y); + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::prev_vertex(double* x, double* y) const + { + return m_vertices.prev_vertex(x, y); + } + + //------------------------------------------------------------------------ + template<class VC> + inline double path_base<VC>::last_x() const + { + return m_vertices.last_x(); + } + + //------------------------------------------------------------------------ + template<class VC> + inline double path_base<VC>::last_y() const + { + return m_vertices.last_y(); + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::vertex(unsigned idx, double* x, double* y) const + { + return m_vertices.vertex(idx, x, y); + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::command(unsigned idx) const + { + return m_vertices.command(idx); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::modify_vertex(unsigned idx, double x, double y) + { + m_vertices.modify_vertex(idx, x, y); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::modify_vertex(unsigned idx, double x, double y, unsigned cmd) + { + m_vertices.modify_vertex(idx, x, y, cmd); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::modify_command(unsigned idx, unsigned cmd) + { + m_vertices.modify_command(idx, cmd); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::rewind(unsigned path_id) + { + m_iterator = path_id; + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::vertex(double* x, double* y) + { + if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop; + return m_vertices.vertex(m_iterator++, x, y); + } + + //------------------------------------------------------------------------ + template<class VC> + unsigned path_base<VC>::perceive_polygon_orientation(unsigned start, + unsigned end) + { + // Calculate signed area (double area to be exact) + //--------------------- + unsigned np = end - start; + double area = 0.0; + unsigned i; + for(i = 0; i < np; i++) + { + double x1, y1, x2, y2; + m_vertices.vertex(start + i, &x1, &y1); + m_vertices.vertex(start + (i + 1) % np, &x2, &y2); + area += x1 * y2 - y1 * x2; + } + return (area < 0.0) ? path_flags_cw : path_flags_ccw; + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::invert_polygon(unsigned start, unsigned end) + { + unsigned i; + unsigned tmp_cmd = m_vertices.command(start); + + --end; // Make "end" inclusive + + // Shift all commands to one position + for(i = start; i < end; i++) + { + m_vertices.modify_command(i, m_vertices.command(i + 1)); + } + + // Assign starting command to the ending command + m_vertices.modify_command(end, tmp_cmd); + + // Reverse the polygon + while(end > start) + { + m_vertices.swap_vertices(start++, end--); + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::invert_polygon(unsigned start) + { + // Skip all non-vertices at the beginning + while(start < m_vertices.total_vertices() && + !is_vertex(m_vertices.command(start))) ++start; + + // Skip all insignificant move_to + while(start+1 < m_vertices.total_vertices() && + is_move_to(m_vertices.command(start)) && + is_move_to(m_vertices.command(start+1))) ++start; + + // Find the last vertex + unsigned end = start + 1; + while(end < m_vertices.total_vertices() && + !is_next_poly(m_vertices.command(end))) ++end; + + invert_polygon(start, end); + } + + //------------------------------------------------------------------------ + template<class VC> + unsigned path_base<VC>::arrange_polygon_orientation(unsigned start, + path_flags_e orientation) + { + if(orientation == path_flags_none) return start; + + // Skip all non-vertices at the beginning + while(start < m_vertices.total_vertices() && + !is_vertex(m_vertices.command(start))) ++start; + + // Skip all insignificant move_to + while(start+1 < m_vertices.total_vertices() && + is_move_to(m_vertices.command(start)) && + is_move_to(m_vertices.command(start+1))) ++start; + + // Find the last vertex + unsigned end = start + 1; + while(end < m_vertices.total_vertices() && + !is_next_poly(m_vertices.command(end))) ++end; + + if(end - start > 2) + { + if(perceive_polygon_orientation(start, end) != unsigned(orientation)) + { + // Invert polygon, set orientation flag, and skip all end_poly + invert_polygon(start, end); + unsigned cmd; + while(end < m_vertices.total_vertices() && + is_end_poly(cmd = m_vertices.command(end))) + { + m_vertices.modify_command(end++, set_orientation(cmd, orientation)); + } + } + } + return end; + } + + //------------------------------------------------------------------------ + template<class VC> + unsigned path_base<VC>::arrange_orientations(unsigned start, + path_flags_e orientation) + { + if(orientation != path_flags_none) + { + while(start < m_vertices.total_vertices()) + { + start = arrange_polygon_orientation(start, orientation); + if(is_stop(m_vertices.command(start))) + { + ++start; + break; + } + } + } + return start; + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::arrange_orientations_all_paths(path_flags_e orientation) + { + if(orientation != path_flags_none) + { + unsigned start = 0; + while(start < m_vertices.total_vertices()) + { + start = arrange_orientations(start, orientation); + } + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::flip_x(double x1, double x2) + { + unsigned i; + double x, y; + for(i = 0; i < m_vertices.total_vertices(); i++) + { + unsigned cmd = m_vertices.vertex(i, &x, &y); + if(is_vertex(cmd)) + { + m_vertices.modify_vertex(i, x2 - x + x1, y); + } + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::flip_y(double y1, double y2) + { + unsigned i; + double x, y; + for(i = 0; i < m_vertices.total_vertices(); i++) + { + unsigned cmd = m_vertices.vertex(i, &x, &y); + if(is_vertex(cmd)) + { + m_vertices.modify_vertex(i, x, y2 - y + y1); + } + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::translate(double dx, double dy, unsigned path_id) + { + unsigned num_ver = m_vertices.total_vertices(); + for(; path_id < num_ver; path_id++) + { + double x, y; + unsigned cmd = m_vertices.vertex(path_id, &x, &y); + if(is_stop(cmd)) break; + if(is_vertex(cmd)) + { + x += dx; + y += dy; + m_vertices.modify_vertex(path_id, x, y); + } + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::translate_all_paths(double dx, double dy) + { + unsigned idx; + unsigned num_ver = m_vertices.total_vertices(); + for(idx = 0; idx < num_ver; idx++) + { + double x, y; + if(is_vertex(m_vertices.vertex(idx, &x, &y))) + { + x += dx; + y += dy; + m_vertices.modify_vertex(idx, x, y); + } + } + } + + //-----------------------------------------------------vertex_stl_storage + template<class Container> class vertex_stl_storage + { + public: + typedef typename Container::value_type vertex_type; + typedef typename vertex_type::value_type value_type; + + void remove_all() { m_vertices.clear(); } + void free_all() { m_vertices.clear(); } + + void add_vertex(double x, double y, unsigned cmd) + { + m_vertices.push_back(vertex_type(value_type(x), + value_type(y), + int8u(cmd))); + } + + void modify_vertex(unsigned idx, double x, double y) + { + vertex_type& v = m_vertices[idx]; + v.x = value_type(x); + v.y = value_type(y); + } + + void modify_vertex(unsigned idx, double x, double y, unsigned cmd) + { + vertex_type& v = m_vertices[idx]; + v.x = value_type(x); + v.y = value_type(y); + v.cmd = int8u(cmd); + } + + void modify_command(unsigned idx, unsigned cmd) + { + m_vertices[idx].cmd = int8u(cmd); + } + + void swap_vertices(unsigned v1, unsigned v2) + { + vertex_type t = m_vertices[v1]; + m_vertices[v1] = m_vertices[v2]; + m_vertices[v2] = t; + } + + unsigned last_command() const + { + return m_vertices.size() ? + m_vertices[m_vertices.size() - 1].cmd : + path_cmd_stop; + } + + unsigned last_vertex(double* x, double* y) const + { + if(m_vertices.size() == 0) + { + *x = *y = 0.0; + return path_cmd_stop; + } + return vertex(m_vertices.size() - 1, x, y); + } + + unsigned prev_vertex(double* x, double* y) const + { + if(m_vertices.size() < 2) + { + *x = *y = 0.0; + return path_cmd_stop; + } + return vertex(m_vertices.size() - 2, x, y); + } + + double last_x() const + { + return m_vertices.size() ? m_vertices[m_vertices.size() - 1].x : 0.0; + } + + double last_y() const + { + return m_vertices.size() ? m_vertices[m_vertices.size() - 1].y : 0.0; + } + + unsigned total_vertices() const + { + return m_vertices.size(); + } + + unsigned vertex(unsigned idx, double* x, double* y) const + { + const vertex_type& v = m_vertices[idx]; + *x = v.x; + *y = v.y; + return v.cmd; + } + + unsigned command(unsigned idx) const + { + return m_vertices[idx].cmd; + } + + private: + Container m_vertices; + }; + + //-----------------------------------------------------------path_storage + typedef path_base<vertex_block_storage<double> > path_storage; + + // Example of declarations path_storage with pod_bvector as a container + //----------------------------------------------------------------------- + //typedef path_base<vertex_stl_storage<pod_bvector<vertex_d> > > path_storage; + +} + + + +// Example of declarations path_storage with std::vector as a container +//--------------------------------------------------------------------------- +//#include <vector> +//namespace agg +//{ +// typedef path_base<vertex_stl_storage<std::vector<vertex_d> > > stl_path_storage; +//} + + + + +#endif diff --git a/include/agg_path_storage_integer.h b/include/agg_path_storage_integer.h new file mode 100644 index 0000000..1026bde --- /dev/null +++ b/include/agg_path_storage_integer.h @@ -0,0 +1,295 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_PATH_STORAGE_INTEGER_INCLUDED +#define AGG_PATH_STORAGE_INTEGER_INCLUDED + +#include <cstring> +#include "agg_array.h" + +namespace agg +{ + //---------------------------------------------------------vertex_integer + template<class T, unsigned CoordShift=6> struct vertex_integer + { + enum path_cmd + { + cmd_move_to = 0, + cmd_line_to = 1, + cmd_curve3 = 2, + cmd_curve4 = 3 + }; + + enum coord_scale_e + { + coord_shift = CoordShift, + coord_scale = 1 << coord_shift + }; + + T x,y; + vertex_integer() {} + vertex_integer(T x_, T y_, unsigned flag) : + x(((x_ << 1) & ~1) | (flag & 1)), + y(((y_ << 1) & ~1) | (flag >> 1)) {} + + unsigned vertex(double* x_, double* y_, + double dx=0, double dy=0, + double scale=1.0) const + { + *x_ = dx + (double(x >> 1) / coord_scale) * scale; + *y_ = dy + (double(y >> 1) / coord_scale) * scale; + switch(((y & 1) << 1) | (x & 1)) + { + case cmd_move_to: return path_cmd_move_to; + case cmd_line_to: return path_cmd_line_to; + case cmd_curve3: return path_cmd_curve3; + case cmd_curve4: return path_cmd_curve4; + } + return path_cmd_stop; + } + }; + + + //---------------------------------------------------path_storage_integer + template<class T, unsigned CoordShift=6> class path_storage_integer + { + public: + typedef T value_type; + typedef vertex_integer<T, CoordShift> vertex_integer_type; + + //-------------------------------------------------------------------- + path_storage_integer() : m_storage(), m_vertex_idx(0), m_closed(true) {} + + //-------------------------------------------------------------------- + void remove_all() { m_storage.remove_all(); } + + //-------------------------------------------------------------------- + void move_to(T x, T y) + { + m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_move_to)); + } + + //-------------------------------------------------------------------- + void line_to(T x, T y) + { + m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_line_to)); + } + + //-------------------------------------------------------------------- + void curve3(T x_ctrl, T y_ctrl, + T x_to, T y_to) + { + m_storage.add(vertex_integer_type(x_ctrl, y_ctrl, vertex_integer_type::cmd_curve3)); + m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve3)); + } + + //-------------------------------------------------------------------- + void curve4(T x_ctrl1, T y_ctrl1, + T x_ctrl2, T y_ctrl2, + T x_to, T y_to) + { + m_storage.add(vertex_integer_type(x_ctrl1, y_ctrl1, vertex_integer_type::cmd_curve4)); + m_storage.add(vertex_integer_type(x_ctrl2, y_ctrl2, vertex_integer_type::cmd_curve4)); + m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve4)); + } + + //-------------------------------------------------------------------- + void close_polygon() {} + + //-------------------------------------------------------------------- + unsigned size() const { return m_storage.size(); } + unsigned vertex(unsigned idx, double* x, double* y) const + { + return m_storage[idx].vertex(x, y); + } + + //-------------------------------------------------------------------- + unsigned byte_size() const { return m_storage.size() * sizeof(vertex_integer_type); } + void serialize(int8u* ptr) const + { + unsigned i; + for(i = 0; i < m_storage.size(); i++) + { + std::memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type)); + ptr += sizeof(vertex_integer_type); + } + } + + //-------------------------------------------------------------------- + void rewind(unsigned) + { + m_vertex_idx = 0; + m_closed = true; + } + + //-------------------------------------------------------------------- + unsigned vertex(double* x, double* y) + { + if(m_storage.size() < 2 || m_vertex_idx > m_storage.size()) + { + *x = 0; + *y = 0; + return path_cmd_stop; + } + if(m_vertex_idx == m_storage.size()) + { + *x = 0; + *y = 0; + ++m_vertex_idx; + return path_cmd_end_poly | path_flags_close; + } + unsigned cmd = m_storage[m_vertex_idx].vertex(x, y); + if(is_move_to(cmd) && !m_closed) + { + *x = 0; + *y = 0; + m_closed = true; + return path_cmd_end_poly | path_flags_close; + } + m_closed = false; + ++m_vertex_idx; + return cmd; + } + + //-------------------------------------------------------------------- + rect_d bounding_rect() const + { + rect_d bounds(1e100, 1e100, -1e100, -1e100); + if(m_storage.size() == 0) + { + bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0; + } + else + { + unsigned i; + for(i = 0; i < m_storage.size(); i++) + { + double x, y; + m_storage[i].vertex(&x, &y); + if(x < bounds.x1) bounds.x1 = x; + if(y < bounds.y1) bounds.y1 = y; + if(x > bounds.x2) bounds.x2 = x; + if(y > bounds.y2) bounds.y2 = y; + } + } + return bounds; + } + + private: + pod_bvector<vertex_integer_type, 6> m_storage; + unsigned m_vertex_idx; + bool m_closed; + }; + + + + + //-----------------------------------------serialized_integer_path_adaptor + template<class T, unsigned CoordShift=6> class serialized_integer_path_adaptor + { + public: + typedef vertex_integer<T, CoordShift> vertex_integer_type; + + //-------------------------------------------------------------------- + serialized_integer_path_adaptor() : + m_data(0), + m_end(0), + m_ptr(0), + m_dx(0.0), + m_dy(0.0), + m_scale(1.0), + m_vertices(0) + {} + + //-------------------------------------------------------------------- + serialized_integer_path_adaptor(const int8u* data, unsigned size, + double dx, double dy) : + m_data(data), + m_end(data + size), + m_ptr(data), + m_dx(dx), + m_dy(dy), + m_vertices(0) + {} + + //-------------------------------------------------------------------- + void init(const int8u* data, unsigned size, + double dx, double dy, double scale=1.0) + { + m_data = data; + m_end = data + size; + m_ptr = data; + m_dx = dx; + m_dy = dy; + m_scale = scale; + m_vertices = 0; + } + + + //-------------------------------------------------------------------- + void rewind(unsigned) + { + m_ptr = m_data; + m_vertices = 0; + } + + //-------------------------------------------------------------------- + unsigned vertex(double* x, double* y) + { + if(m_data == 0 || m_ptr > m_end) + { + *x = 0; + *y = 0; + return path_cmd_stop; + } + + if(m_ptr == m_end) + { + *x = 0; + *y = 0; + m_ptr += sizeof(vertex_integer_type); + return path_cmd_end_poly | path_flags_close; + } + + vertex_integer_type v; + std::memcpy(&v, m_ptr, sizeof(vertex_integer_type)); + unsigned cmd = v.vertex(x, y, m_dx, m_dy, m_scale); + if(is_move_to(cmd) && m_vertices > 2) + { + *x = 0; + *y = 0; + m_vertices = 0; + return path_cmd_end_poly | path_flags_close; + } + ++m_vertices; + m_ptr += sizeof(vertex_integer_type); + return cmd; + } + + private: + const int8u* m_data; + const int8u* m_end; + const int8u* m_ptr; + double m_dx; + double m_dy; + double m_scale; + unsigned m_vertices; + }; + +} + + +#endif + diff --git a/include/agg_pattern_filters_rgba.h b/include/agg_pattern_filters_rgba.h new file mode 100644 index 0000000..c1d174c --- /dev/null +++ b/include/agg_pattern_filters_rgba.h @@ -0,0 +1,123 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_PATTERN_FILTERS_RGBA8_INCLUDED +#define AGG_PATTERN_FILTERS_RGBA8_INCLUDED + +#include "agg_basics.h" +#include "agg_line_aa_basics.h" +#include "agg_color_rgba.h" + + +namespace agg +{ + + //=======================================================pattern_filter_nn + template<class ColorT> struct pattern_filter_nn + { + typedef ColorT color_type; + static unsigned dilation() { return 0; } + + static void AGG_INLINE pixel_low_res(color_type const* const* buf, + color_type* p, int x, int y) + { + *p = buf[y][x]; + } + + static void AGG_INLINE pixel_high_res(color_type const* const* buf, + color_type* p, int x, int y) + { + *p = buf[y >> line_subpixel_shift] + [x >> line_subpixel_shift]; + } + }; + + typedef pattern_filter_nn<rgba8> pattern_filter_nn_rgba8; + typedef pattern_filter_nn<rgba16> pattern_filter_nn_rgba16; + + + //===========================================pattern_filter_bilinear_rgba + template<class ColorT> struct pattern_filter_bilinear_rgba + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + + + static unsigned dilation() { return 1; } + + static AGG_INLINE void pixel_low_res(color_type const* const* buf, + color_type* p, int x, int y) + { + *p = buf[y][x]; + } + + static AGG_INLINE void pixel_high_res(color_type const* const* buf, + color_type* p, int x, int y) + { + calc_type r, g, b, a; + r = g = b = a = 0; + + calc_type weight; + int x_lr = x >> line_subpixel_shift; + int y_lr = y >> line_subpixel_shift; + + x &= line_subpixel_mask; + y &= line_subpixel_mask; + const color_type* ptr = buf[y_lr] + x_lr; + + weight = (line_subpixel_scale - x) * + (line_subpixel_scale - y); + r += weight * ptr->r; + g += weight * ptr->g; + b += weight * ptr->b; + a += weight * ptr->a; + + ++ptr; + + weight = x * (line_subpixel_scale - y); + r += weight * ptr->r; + g += weight * ptr->g; + b += weight * ptr->b; + a += weight * ptr->a; + + ptr = buf[y_lr + 1] + x_lr; + + weight = (line_subpixel_scale - x) * y; + r += weight * ptr->r; + g += weight * ptr->g; + b += weight * ptr->b; + a += weight * ptr->a; + + ++ptr; + + weight = x * y; + r += weight * ptr->r; + g += weight * ptr->g; + b += weight * ptr->b; + a += weight * ptr->a; + + p->r = (value_type)color_type::downshift(r, line_subpixel_shift * 2); + p->g = (value_type)color_type::downshift(g, line_subpixel_shift * 2); + p->b = (value_type)color_type::downshift(b, line_subpixel_shift * 2); + p->a = (value_type)color_type::downshift(a, line_subpixel_shift * 2); + } + }; + + typedef pattern_filter_bilinear_rgba<rgba8> pattern_filter_bilinear_rgba8; + typedef pattern_filter_bilinear_rgba<rgba16> pattern_filter_bilinear_rgba16; + typedef pattern_filter_bilinear_rgba<rgba32> pattern_filter_bilinear_rgba32; +} + +#endif diff --git a/include/agg_pixfmt_amask_adaptor.h b/include/agg_pixfmt_amask_adaptor.h new file mode 100644 index 0000000..fa44598 --- /dev/null +++ b/include/agg_pixfmt_amask_adaptor.h @@ -0,0 +1,240 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED +#define AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED + + +#include <cstring> +#include "agg_array.h" +#include "agg_rendering_buffer.h" + + +namespace agg +{ + //==================================================pixfmt_amask_adaptor + template<class PixFmt, class AlphaMask> class pixfmt_amask_adaptor + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::row_data row_data; + typedef AlphaMask amask_type; + typedef typename amask_type::cover_type cover_type; + + private: + enum span_extra_tail_e { span_extra_tail = 256 }; + + void realloc_span(unsigned len) + { + if(len > m_span.size()) + { + m_span.resize(len + span_extra_tail); + } + } + + void init_span(unsigned len) + { + realloc_span(len); + std::memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type)); + } + + void init_span(unsigned len, const cover_type* covers) + { + realloc_span(len); + std::memcpy(&m_span[0], covers, len * sizeof(cover_type)); + } + + + public: + pixfmt_amask_adaptor(pixfmt_type& pixf, amask_type& mask) : + m_pixf(&pixf), m_mask(&mask), m_span() + {} + + void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; } + void attach_alpha_mask(amask_type& mask) { m_mask = &mask; } + + //-------------------------------------------------------------------- + template<class PixFmt2> + bool attach_pixfmt(PixFmt2& pixf, int x1, int y1, int x2, int y2) + { + return m_pixf->attach(pixf, x1, y1, x2, y2); + } + + //-------------------------------------------------------------------- + unsigned width() const { return m_pixf->width(); } + unsigned height() const { return m_pixf->height(); } + + //-------------------------------------------------------------------- + color_type pixel(int x, int y) + { + return m_pixf->pixel(x, y); + } + + //-------------------------------------------------------------------- + void copy_pixel(int x, int y, const color_type& c) + { + m_pixf->blend_pixel(x, y, c, m_mask->pixel(x, y)); + } + + //-------------------------------------------------------------------- + void blend_pixel(int x, int y, const color_type& c, cover_type cover) + { + m_pixf->blend_pixel(x, y, c, m_mask->combine_pixel(x, y, cover)); + } + + //-------------------------------------------------------------------- + void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + realloc_span(len); + m_mask->fill_hspan(x, y, &m_span[0], len); + m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, + unsigned len, + const color_type& c, + cover_type) + { + init_span(len); + m_mask->combine_hspan(x, y, &m_span[0], len); + m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]); + } + + //-------------------------------------------------------------------- + void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + realloc_span(len); + m_mask->fill_vspan(x, y, &m_span[0], len); + m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]); + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, + unsigned len, + const color_type& c, + cover_type) + { + init_span(len); + m_mask->combine_vspan(x, y, &m_span[0], len); + m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]); + } + + //-------------------------------------------------------------------- + void copy_from(const rendering_buffer& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + m_pixf->copy_from(from, xdst, ydst, xsrc, ysrc, len); + } + + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, + unsigned len, + const color_type& c, + const cover_type* covers) + { + init_span(len, covers); + m_mask->combine_hspan(x, y, &m_span[0], len); + m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]); + } + + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const cover_type* covers) + { + init_span(len, covers); + m_mask->combine_vspan(x, y, &m_span[0], len); + m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]); + } + + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, unsigned len, const color_type* colors) + { + realloc_span(len); + m_mask->fill_hspan(x, y, &m_span[0], len); + m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover_full); + } + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, unsigned len, const color_type* colors) + { + realloc_span(len); + m_mask->fill_vspan(x, y, &m_span[0], len); + m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover_full); + } + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, + unsigned len, + const color_type* colors, + const cover_type* covers, + cover_type cover = cover_full) + { + if(covers) + { + init_span(len, covers); + m_mask->combine_hspan(x, y, &m_span[0], len); + } + else + { + realloc_span(len); + m_mask->fill_hspan(x, y, &m_span[0], len); + } + m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover); + } + + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, + unsigned len, + const color_type* colors, + const cover_type* covers, + cover_type cover = cover_full) + { + if(covers) + { + init_span(len, covers); + m_mask->combine_vspan(x, y, &m_span[0], len); + } + else + { + realloc_span(len); + m_mask->fill_vspan(x, y, &m_span[0], len); + } + m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover); + } + + private: + pixfmt_type* m_pixf; + const amask_type* m_mask; + pod_array<cover_type> m_span; + }; + +} + +#endif + diff --git a/include/agg_pixfmt_base.h b/include/agg_pixfmt_base.h new file mode 100644 index 0000000..8d5a629 --- /dev/null +++ b/include/agg_pixfmt_base.h @@ -0,0 +1,97 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_PIXFMT_BASE_INCLUDED +#define AGG_PIXFMT_BASE_INCLUDED + +#include "agg_basics.h" +#include "agg_color_gray.h" +#include "agg_color_rgba.h" + +namespace agg +{ + struct pixfmt_gray_tag + { + }; + + struct pixfmt_rgb_tag + { + }; + + struct pixfmt_rgba_tag + { + }; + + //--------------------------------------------------------------blender_base + template<class ColorT, class Order = void> + struct blender_base + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + + static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full) + { + if (cover > cover_none) + { + rgba c( + color_type::to_double(r), + color_type::to_double(g), + color_type::to_double(b), + color_type::to_double(a)); + + if (cover < cover_full) + { + double x = double(cover) / cover_full; + c.r *= x; + c.g *= x; + c.b *= x; + c.a *= x; + } + + return c; + } + else return rgba::no_color(); + } + + static rgba get(const value_type* p, cover_type cover = cover_full) + { + return get( + p[order_type::R], + p[order_type::G], + p[order_type::B], + p[order_type::A], + cover); + } + + static void set(value_type* p, value_type r, value_type g, value_type b, value_type a) + { + p[order_type::R] = r; + p[order_type::G] = g; + p[order_type::B] = b; + p[order_type::A] = a; + } + + static void set(value_type* p, const rgba& c) + { + p[order_type::R] = color_type::from_double(c.r); + p[order_type::G] = color_type::from_double(c.g); + p[order_type::B] = color_type::from_double(c.b); + p[order_type::A] = color_type::from_double(c.a); + } + }; +} + +#endif diff --git a/include/agg_pixfmt_gray.h b/include/agg_pixfmt_gray.h new file mode 100644 index 0000000..3f99087 --- /dev/null +++ b/include/agg_pixfmt_gray.h @@ -0,0 +1,738 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_PIXFMT_GRAY_INCLUDED +#define AGG_PIXFMT_GRAY_INCLUDED + +#include <cstring> +#include "agg_pixfmt_base.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + + //============================================================blender_gray + template<class ColorT> struct blender_gray + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. Since the render buffer is opaque we skip the + // initial premultiply and final demultiply. + + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha, cover_type cover) + { + blend_pix(p, cv, color_type::mult_cover(alpha, cover)); + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha) + { + *p = color_type::lerp(*p, cv, alpha); + } + }; + + + //======================================================blender_gray_pre + template<class ColorT> struct blender_gray_pre + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the premultiplied form of Alvy-Ray Smith's + // compositing function. + + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha, cover_type cover) + { + blend_pix(p, color_type::mult_cover(cv, cover), color_type::mult_cover(alpha, cover)); + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha) + { + *p = color_type::prelerp(*p, cv, alpha); + } + }; + + + + //=====================================================apply_gamma_dir_gray + template<class ColorT, class GammaLut> class apply_gamma_dir_gray + { + public: + typedef typename ColorT::value_type value_type; + + apply_gamma_dir_gray(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + *p = m_gamma.dir(*p); + } + + private: + const GammaLut& m_gamma; + }; + + + + //=====================================================apply_gamma_inv_gray + template<class ColorT, class GammaLut> class apply_gamma_inv_gray + { + public: + typedef typename ColorT::value_type value_type; + + apply_gamma_inv_gray(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + *p = m_gamma.inv(*p); + } + + private: + const GammaLut& m_gamma; + }; + + + + //=================================================pixfmt_alpha_blend_gray + template<class Blender, class RenBuf, unsigned Step = 1, unsigned Offset = 0> + class pixfmt_alpha_blend_gray + { + public: + typedef pixfmt_gray_tag pixfmt_category; + typedef RenBuf rbuf_type; + typedef typename rbuf_type::row_data row_data; + typedef Blender blender_type; + typedef typename blender_type::color_type color_type; + typedef int order_type; // A fake one + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + enum + { + num_components = 1, + pix_width = sizeof(value_type) * Step, + pix_step = Step, + pix_offset = Offset, + }; + struct pixel_type + { + value_type c[num_components]; + + void set(value_type v) + { + c[0] = v; + } + + void set(const color_type& color) + { + set(color.v); + } + + void get(value_type& v) const + { + v = c[0]; + } + + color_type get() const + { + return color_type(c[0]); + } + + pixel_type* next() + { + return (pixel_type*)(c + pix_step); + } + + const pixel_type* next() const + { + return (const pixel_type*)(c + pix_step); + } + + pixel_type* advance(int n) + { + return (pixel_type*)(c + n * pix_step); + } + + const pixel_type* advance(int n) const + { + return (const pixel_type*)(c + n * pix_step); + } + }; + + private: + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, + value_type v, value_type a, + unsigned cover) + { + blender_type::blend_pix(p->c, v, a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, value_type v, value_type a) + { + blender_type::blend_pix(p->c, v, a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + blender_type::blend_pix(p->c, c.v, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c) + { + blender_type::blend_pix(p->c, c.v, c.a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, cover); + } + } + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c) + { + if (!c.is_transparent()) + { + if (c.is_opaque()) + { + p->set(c); + } + else + { + blend_pix(p, c); + } + } + } + + public: + //-------------------------------------------------------------------- + explicit pixfmt_alpha_blend_gray(rbuf_type& rb) : + m_rbuf(&rb) + {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + //-------------------------------------------------------------------- + + template<class PixFmt> + bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) + { + rect_i r(x1, y1, x2, y2); + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + { + int stride = pixf.stride(); + m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), + (r.x2 - r.x1) + 1, + (r.y2 - r.y1) + 1, + stride); + return true; + } + return false; + } + + //-------------------------------------------------------------------- + AGG_INLINE unsigned width() const { return m_rbuf->width(); } + AGG_INLINE unsigned height() const { return m_rbuf->height(); } + AGG_INLINE int stride() const { return m_rbuf->stride(); } + + //-------------------------------------------------------------------- + int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } + const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } + row_data row(int y) const { return m_rbuf->row(y); } + + //-------------------------------------------------------------------- + AGG_INLINE int8u* pix_ptr(int x, int y) + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const + { + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)((value_type*)p + pix_offset); + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)((const value_type*)p + pix_offset); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void write_plain_color(void* p, color_type c) + { + // Grayscale formats are implicitly premultiplied. + c.premultiply(); + pix_value_ptr(p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE static color_type read_plain_color(const void* p) + { + return pix_value_ptr(p)->get(); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void make_pix(int8u* p, const color_type& c) + { + ((pixel_type*)p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + pix_value_ptr(x, y, 1)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type* p = pix_value_ptr(x, y, len); + do + { + p->set(c); + p = p->next(); + } + while(--len); + } + + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + do + { + pix_value_ptr(x, y++, 1)->set(c); + } + while (--len); + } + + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + + if (c.is_opaque() && cover == cover_mask) + { + do + { + p->set(c); + p = p->next(); + } + while (--len); + } + else + { + do + { + blend_pix(p, c, cover); + p = p->next(); + } + while (--len); + } + } + } + + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + do + { + pix_value_ptr(x, y++, 1)->set(c); + } + while (--len); + } + else + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, cover); + } + while (--len); + } + } + } + + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + p = p->next(); + ++covers; + } + while (--len); + } + } + + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + do + { + pixel_type* p = pix_value_ptr(x, y++, 1); + + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + ++covers; + } + while (--len); + } + } + + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + p->set(*colors++); + p = p->next(); + } + while (--len); + } + + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + do + { + pix_value_ptr(x, y++, 1)->set(*colors++); + } + while (--len); + } + + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + pixel_type* p = pix_value_ptr(x, y, len); + + if (covers) + { + do + { + copy_or_blend_pix(p, *colors++, *covers++); + p = p->next(); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(p, *colors++); + p = p->next(); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(p, *colors++, cover); + p = p->next(); + } + while (--len); + } + } + } + + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + if (covers) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + template<class Function> void for_each_pixel(Function f) + { + unsigned y; + for (y = 0; y < height(); ++y) + { + row_data r = m_rbuf->row(y); + if (r.ptr) + { + unsigned len = r.x2 - r.x1 + 1; + pixel_type* p = pix_value_ptr(r.x1, y, len); + do + { + f(p->c); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class RenBuf2> + void copy_from(const RenBuf2& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + if (const int8u* p = from.row_ptr(ysrc)) + { + std::memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, + p + xsrc * pix_width, + len * pix_width); + } + } + + //-------------------------------------------------------------------- + // Blend from single color, using grayscale surface as alpha channel. + template<class SrcPixelFormatRenderer> + void blend_from_color(const SrcPixelFormatRenderer& from, + const color_type& color, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. + template<class SrcPixelFormatRenderer> + void blend_from_lut(const SrcPixelFormatRenderer& from, + const color_type* color_lut, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + private: + rbuf_type* m_rbuf; + }; + + typedef blender_gray<gray8> blender_gray8; + typedef blender_gray<sgray8> blender_sgray8; + typedef blender_gray<gray16> blender_gray16; + typedef blender_gray<gray32> blender_gray32; + + typedef blender_gray_pre<gray8> blender_gray8_pre; + typedef blender_gray_pre<sgray8> blender_sgray8_pre; + typedef blender_gray_pre<gray16> blender_gray16_pre; + typedef blender_gray_pre<gray32> blender_gray32_pre; + + typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8; + typedef pixfmt_alpha_blend_gray<blender_sgray8, rendering_buffer> pixfmt_sgray8; + typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16; + typedef pixfmt_alpha_blend_gray<blender_gray32, rendering_buffer> pixfmt_gray32; + + typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre; + typedef pixfmt_alpha_blend_gray<blender_sgray8_pre, rendering_buffer> pixfmt_sgray8_pre; + typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre; + typedef pixfmt_alpha_blend_gray<blender_gray32_pre, rendering_buffer> pixfmt_gray32_pre; +} + +#endif + diff --git a/include/agg_pixfmt_rgb.h b/include/agg_pixfmt_rgb.h new file mode 100644 index 0000000..044654d --- /dev/null +++ b/include/agg_pixfmt_rgb.h @@ -0,0 +1,995 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_PIXFMT_RGB_INCLUDED +#define AGG_PIXFMT_RGB_INCLUDED + +#include <cstring> +#include "agg_pixfmt_base.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + + //=====================================================apply_gamma_dir_rgb + template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgb + { + public: + typedef typename ColorT::value_type value_type; + + apply_gamma_dir_rgb(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + p[Order::R] = m_gamma.dir(p[Order::R]); + p[Order::G] = m_gamma.dir(p[Order::G]); + p[Order::B] = m_gamma.dir(p[Order::B]); + } + + private: + const GammaLut& m_gamma; + }; + + + + //=====================================================apply_gamma_inv_rgb + template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgb + { + public: + typedef typename ColorT::value_type value_type; + + apply_gamma_inv_rgb(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + p[Order::R] = m_gamma.inv(p[Order::R]); + p[Order::G] = m_gamma.inv(p[Order::G]); + p[Order::B] = m_gamma.inv(p[Order::B]); + } + + private: + const GammaLut& m_gamma; + }; + + + //=========================================================blender_rgb + template<class ColorT, class Order> + struct blender_rgb + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. Since the render buffer is opaque we skip the + // initial premultiply and final demultiply. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + p[Order::R] = color_type::lerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::lerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::lerp(p[Order::B], cb, alpha); + } + }; + + //======================================================blender_rgb_pre + template<class ColorT, class Order> + struct blender_rgb_pre + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the premultiplied form of Alvy-Ray Smith's + // compositing function. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, + color_type::mult_cover(cr, cover), + color_type::mult_cover(cg, cover), + color_type::mult_cover(cb, cover), + color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha); + } + }; + + //===================================================blender_rgb_gamma + template<class ColorT, class Order, class Gamma> + class blender_rgb_gamma : public blender_base<ColorT, Order> + { + public: + typedef ColorT color_type; + typedef Order order_type; + typedef Gamma gamma_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + blender_rgb_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + calc_type r = m_gamma->dir(p[Order::R]); + calc_type g = m_gamma->dir(p[Order::G]); + calc_type b = m_gamma->dir(p[Order::B]); + p[Order::R] = m_gamma->inv(color_type::downscale((m_gamma->dir(cr) - r) * alpha) + r); + p[Order::G] = m_gamma->inv(color_type::downscale((m_gamma->dir(cg) - g) * alpha) + g); + p[Order::B] = m_gamma->inv(color_type::downscale((m_gamma->dir(cb) - b) * alpha) + b); + } + + private: + const gamma_type* m_gamma; + }; + + + //==================================================pixfmt_alpha_blend_rgb + template<class Blender, class RenBuf, unsigned Step, unsigned Offset = 0> + class pixfmt_alpha_blend_rgb + { + public: + typedef pixfmt_rgb_tag pixfmt_category; + typedef RenBuf rbuf_type; + typedef Blender blender_type; + typedef typename rbuf_type::row_data row_data; + typedef typename blender_type::color_type color_type; + typedef typename blender_type::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + enum + { + num_components = 3, + pix_step = Step, + pix_offset = Offset, + pix_width = sizeof(value_type) * pix_step + }; + struct pixel_type + { + value_type c[num_components]; + + void set(value_type r, value_type g, value_type b) + { + c[order_type::R] = r; + c[order_type::G] = g; + c[order_type::B] = b; + } + + void set(const color_type& color) + { + set(color.r, color.g, color.b); + } + + void get(value_type& r, value_type& g, value_type& b) const + { + r = c[order_type::R]; + g = c[order_type::G]; + b = c[order_type::B]; + } + + color_type get() const + { + return color_type( + c[order_type::R], + c[order_type::G], + c[order_type::B]); + } + + pixel_type* next() + { + return (pixel_type*)(c + pix_step); + } + + const pixel_type* next() const + { + return (const pixel_type*)(c + pix_step); + } + + pixel_type* advance(int n) + { + return (pixel_type*)(c + n * pix_step); + } + + const pixel_type* advance(int n) const + { + return (const pixel_type*)(c + n * pix_step); + } + }; + + private: + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, + value_type r, value_type g, value_type b, value_type a, + unsigned cover) + { + m_blender.blend_pix(p->c, r, g, b, a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, + value_type r, value_type g, value_type b, value_type a) + { + m_blender.blend_pix(p->c, r, g, b, a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, cover); + } + } + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c) + { + if (!c.is_transparent()) + { + if (c.is_opaque()) + { + p->set(c); + } + else + { + blend_pix(p, c); + } + } + } + + public: + //-------------------------------------------------------------------- + explicit pixfmt_alpha_blend_rgb(rbuf_type& rb) : + m_rbuf(&rb) + {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + + //-------------------------------------------------------------------- + template<class PixFmt> + bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) + { + rect_i r(x1, y1, x2, y2); + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + { + int stride = pixf.stride(); + m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), + (r.x2 - r.x1) + 1, + (r.y2 - r.y1) + 1, + stride); + return true; + } + return false; + } + + //-------------------------------------------------------------------- + Blender& blender() { return m_blender; } + + //-------------------------------------------------------------------- + AGG_INLINE unsigned width() const { return m_rbuf->width(); } + AGG_INLINE unsigned height() const { return m_rbuf->height(); } + AGG_INLINE int stride() const { return m_rbuf->stride(); } + + //-------------------------------------------------------------------- + AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } + AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } + AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } + + //-------------------------------------------------------------------- + AGG_INLINE int8u* pix_ptr(int x, int y) + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const + { + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)((value_type*)p + pix_offset); + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)((const value_type*)p + pix_offset); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void write_plain_color(void* p, color_type c) + { + // RGB formats are implicitly premultiplied. + c.premultiply(); + pix_value_ptr(p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE static color_type read_plain_color(const void* p) + { + return pix_value_ptr(p)->get(); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void make_pix(int8u* p, const color_type& c) + { + ((pixel_type*)p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + pix_value_ptr(x, y, 1)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type* p = pix_value_ptr(x, y, len); + do + { + p->set(c); + p = p->next(); + } + while(--len); + } + + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + do + { + pix_value_ptr(x, y++, 1)->set(c); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + + if (c.is_opaque() && cover == cover_mask) + { + do + { + p->set(c); + p = p->next(); + } + while (--len); + } + else + { + do + { + blend_pix(p, c, cover); + p = p->next(); + } + while (--len); + } + } + } + + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + do + { + pix_value_ptr(x, y++, 1)->set(c); + } + while (--len); + } + else + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, cover); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + p = p->next(); + ++covers; + } + while (--len); + } + } + + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + do + { + pixel_type* p = pix_value_ptr(x, y++, 1); + + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + ++covers; + } + while (--len); + } + } + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + p->set(*colors++); + p = p->next(); + } + while (--len); + } + + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + do + { + pix_value_ptr(x, y++, 1)->set(*colors++); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + pixel_type* p = pix_value_ptr(x, y, len); + + if (covers) + { + do + { + copy_or_blend_pix(p, *colors++, *covers++); + p = p->next(); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(p, *colors++); + p = p->next(); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(p, *colors++, cover); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + if (covers) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + template<class Function> void for_each_pixel(Function f) + { + for (unsigned y = 0; y < height(); ++y) + { + row_data r = m_rbuf->row(y); + if (r.ptr) + { + unsigned len = r.x2 - r.x1 + 1; + pixel_type* p = pix_value_ptr(r.x1, y, len); + do + { + f(p->c); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_rgb<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_rgb<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class RenBuf2> + void copy_from(const RenBuf2& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + if (const int8u* p = from.row_ptr(ysrc)) + { + std::memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, + p + xsrc * pix_width, + len * pix_width); + } + } + + //-------------------------------------------------------------------- + // Blend from an RGBA surface. + template<class SrcPixelFormatRenderer> + void blend_from(const SrcPixelFormatRenderer& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::order_type src_order; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + if (cover == cover_mask) + { + do + { + value_type alpha = psrc->c[src_order::A]; + if (alpha <= color_type::empty_value()) + { + if (alpha >= color_type::full_value()) + { + pdst->c[order_type::R] = psrc->c[src_order::R]; + pdst->c[order_type::G] = psrc->c[src_order::G]; + pdst->c[order_type::B] = psrc->c[src_order::B]; + } + else + { + blend_pix(pdst, + psrc->c[src_order::R], + psrc->c[src_order::G], + psrc->c[src_order::B], + alpha); + } + } + psrc = psrc->next(); + pdst = pdst->next(); + } + while(--len); + } + else + { + do + { + copy_or_blend_pix(pdst, psrc->get(), cover); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + // Blend from single color, using grayscale surface as alpha channel. + template<class SrcPixelFormatRenderer> + void blend_from_color(const SrcPixelFormatRenderer& from, + const color_type& color, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. + template<class SrcPixelFormatRenderer> + void blend_from_lut(const SrcPixelFormatRenderer& from, + const color_type* color_lut, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + if (cover == cover_mask) + { + do + { + const color_type& color = color_lut[psrc->c[0]]; + blend_pix(pdst, color); + psrc = psrc->next(); + pdst = pdst->next(); + } + while(--len); + } + else + { + do + { + copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); + } + while(--len); + } + } + } + + private: + rbuf_type* m_rbuf; + Blender m_blender; + }; + + //----------------------------------------------------------------------- + typedef blender_rgb<rgba8, order_rgb> blender_rgb24; + typedef blender_rgb<rgba8, order_bgr> blender_bgr24; + typedef blender_rgb<srgba8, order_rgb> blender_srgb24; + typedef blender_rgb<srgba8, order_bgr> blender_sbgr24; + typedef blender_rgb<rgba16, order_rgb> blender_rgb48; + typedef blender_rgb<rgba16, order_bgr> blender_bgr48; + typedef blender_rgb<rgba32, order_rgb> blender_rgb96; + typedef blender_rgb<rgba32, order_bgr> blender_bgr96; + + typedef blender_rgb_pre<rgba8, order_rgb> blender_rgb24_pre; + typedef blender_rgb_pre<rgba8, order_bgr> blender_bgr24_pre; + typedef blender_rgb_pre<srgba8, order_rgb> blender_srgb24_pre; + typedef blender_rgb_pre<srgba8, order_bgr> blender_sbgr24_pre; + typedef blender_rgb_pre<rgba16, order_rgb> blender_rgb48_pre; + typedef blender_rgb_pre<rgba16, order_bgr> blender_bgr48_pre; + typedef blender_rgb_pre<rgba32, order_rgb> blender_rgb96_pre; + typedef blender_rgb_pre<rgba32, order_bgr> blender_bgr96_pre; + + typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 3> pixfmt_rgb24; + typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 3> pixfmt_bgr24; + typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 3> pixfmt_srgb24; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 3> pixfmt_sbgr24; + typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 3> pixfmt_rgb48; + typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 3> pixfmt_bgr48; + typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 3> pixfmt_rgb96; + typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 3> pixfmt_bgr96; + + typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 3> pixfmt_rgb24_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 3> pixfmt_bgr24_pre; + typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 3> pixfmt_srgb24_pre; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 3> pixfmt_sbgr24_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 3> pixfmt_rgb48_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 3> pixfmt_bgr48_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 3> pixfmt_rgb96_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 3> pixfmt_bgr96_pre; + + typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 4, 0> pixfmt_rgbx32; + typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 4, 1> pixfmt_xrgb32; + typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 4, 1> pixfmt_xbgr32; + typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 4, 0> pixfmt_bgrx32; + typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 4, 0> pixfmt_srgbx32; + typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 4, 1> pixfmt_sxrgb32; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 4, 1> pixfmt_sxbgr32; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 4, 0> pixfmt_sbgrx32; + typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 4, 0> pixfmt_rgbx64; + typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 4, 1> pixfmt_xrgb64; + typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 4, 1> pixfmt_xbgr64; + typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 4, 0> pixfmt_bgrx64; + typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 4, 0> pixfmt_rgbx128; + typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 4, 1> pixfmt_xrgb128; + typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 4, 1> pixfmt_xbgr128; + typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 4, 0> pixfmt_bgrx128; + + typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 4, 0> pixfmt_rgbx32_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 4, 1> pixfmt_xrgb32_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 4, 1> pixfmt_xbgr32_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 4, 0> pixfmt_bgrx32_pre; + typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 4, 0> pixfmt_srgbx32_pre; + typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 4, 1> pixfmt_sxrgb32_pre; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 4, 1> pixfmt_sxbgr32_pre; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 4, 0> pixfmt_sbgrx32_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 4, 0> pixfmt_rgbx64_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 4, 1> pixfmt_xrgb64_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 4, 1> pixfmt_xbgr64_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 4, 0> pixfmt_bgrx64_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 4, 0> pixfmt_rgbx128_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 4, 1> pixfmt_xrgb128_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 4, 1> pixfmt_xbgr128_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 4, 0> pixfmt_bgrx128_pre; + + + //-----------------------------------------------------pixfmt_rgb24_gamma + template<class Gamma> class pixfmt_rgb24_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_srgb24_gamma + template<class Gamma> class pixfmt_srgb24_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_rgb, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_srgb24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_rgb, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_bgr24_gamma + template<class Gamma> class pixfmt_bgr24_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_sbgr24_gamma + template<class Gamma> class pixfmt_sbgr24_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_bgr, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_sbgr24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_bgr, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_rgb48_gamma + template<class Gamma> class pixfmt_rgb48_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_bgr48_gamma + template<class Gamma> class pixfmt_bgr48_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + +} + +#endif + diff --git a/include/agg_pixfmt_rgb_packed.h b/include/agg_pixfmt_rgb_packed.h new file mode 100644 index 0000000..eac6d42 --- /dev/null +++ b/include/agg_pixfmt_rgb_packed.h @@ -0,0 +1,1312 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_PIXFMT_RGB_PACKED_INCLUDED +#define AGG_PIXFMT_RGB_PACKED_INCLUDED + +#include <cstring> +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + //=========================================================blender_rgb555 + struct blender_rgb555 + { + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = (rgb >> 7) & 0xF8; + calc_type g = (rgb >> 2) & 0xF8; + calc_type b = (rgb << 3) & 0xF8; + *p = (pixel_type) + (((((cr - r) * alpha + (r << 8)) >> 1) & 0x7C00) | + ((((cg - g) * alpha + (g << 8)) >> 6) & 0x03E0) | + (((cb - b) * alpha + (b << 8)) >> 11) | 0x8000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 7) | + ((g & 0xF8) << 2) | + (b >> 3) | 0x8000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 7) & 0xF8, + (p >> 2) & 0xF8, + (p << 3) & 0xF8); + } + }; + + + //=====================================================blender_rgb555_pre + struct blender_rgb555_pre + { + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + pixel_type rgb = *p; + calc_type r = (rgb >> 7) & 0xF8; + calc_type g = (rgb >> 2) & 0xF8; + calc_type b = (rgb << 3) & 0xF8; + *p = (pixel_type) + ((((r * alpha + cr * cover) >> 1) & 0x7C00) | + (((g * alpha + cg * cover) >> 6) & 0x03E0) | + ((b * alpha + cb * cover) >> 11) | 0x8000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 7) | + ((g & 0xF8) << 2) | + (b >> 3) | 0x8000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 7) & 0xF8, + (p >> 2) & 0xF8, + (p << 3) & 0xF8); + } + }; + + + + + //=====================================================blender_rgb555_gamma + template<class Gamma> class blender_rgb555_gamma + { + public: + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + typedef Gamma gamma_type; + + blender_rgb555_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = m_gamma->dir((rgb >> 7) & 0xF8); + calc_type g = m_gamma->dir((rgb >> 2) & 0xF8); + calc_type b = m_gamma->dir((rgb << 3) & 0xF8); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 7) & 0x7C00) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 2) & 0x03E0) | + (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3) | 0x8000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 7) | + ((g & 0xF8) << 2) | + (b >> 3) | 0x8000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 7) & 0xF8, + (p >> 2) & 0xF8, + (p << 3) & 0xF8); + } + + private: + const Gamma* m_gamma; + }; + + + + + + //=========================================================blender_rgb565 + struct blender_rgb565 + { + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = (rgb >> 8) & 0xF8; + calc_type g = (rgb >> 3) & 0xFC; + calc_type b = (rgb << 3) & 0xF8; + *p = (pixel_type) + (((((cr - r) * alpha + (r << 8)) ) & 0xF800) | + ((((cg - g) * alpha + (g << 8)) >> 5) & 0x07E0) | + (((cb - b) * alpha + (b << 8)) >> 11)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 8) & 0xF8, + (p >> 3) & 0xFC, + (p << 3) & 0xF8); + } + }; + + + + //=====================================================blender_rgb565_pre + struct blender_rgb565_pre + { + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + pixel_type rgb = *p; + calc_type r = (rgb >> 8) & 0xF8; + calc_type g = (rgb >> 3) & 0xFC; + calc_type b = (rgb << 3) & 0xF8; + *p = (pixel_type) + ((((r * alpha + cr * cover) ) & 0xF800) | + (((g * alpha + cg * cover) >> 5 ) & 0x07E0) | + ((b * alpha + cb * cover) >> 11)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 8) & 0xF8, + (p >> 3) & 0xFC, + (p << 3) & 0xF8); + } + }; + + + + //=====================================================blender_rgb565_gamma + template<class Gamma> class blender_rgb565_gamma + { + public: + typedef rgba8 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int16u pixel_type; + typedef Gamma gamma_type; + + blender_rgb565_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = m_gamma->dir((rgb >> 8) & 0xF8); + calc_type g = m_gamma->dir((rgb >> 3) & 0xFC); + calc_type b = m_gamma->dir((rgb << 3) & 0xF8); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 8) & 0xF800) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 3) & 0x07E0) | + (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 8) & 0xF8, + (p >> 3) & 0xFC, + (p << 3) & 0xF8); + } + + private: + const Gamma* m_gamma; + }; + + + + //=====================================================blender_rgbAAA + struct blender_rgbAAA + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = (rgb >> 14) & 0xFFC0; + calc_type g = (rgb >> 4) & 0xFFC0; + calc_type b = (rgb << 6) & 0xFFC0; + *p = (pixel_type) + (((((cr - r) * alpha + (r << 16)) >> 2) & 0x3FF00000) | + ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) | + (((cb - b) * alpha + (b << 16)) >> 22) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (b >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 14) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p << 6) & 0xFFC0); + } + }; + + + + //==================================================blender_rgbAAA_pre + struct blender_rgbAAA_pre + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + cover = (cover + 1) << (color_type::base_shift - 8); + pixel_type rgb = *p; + calc_type r = (rgb >> 14) & 0xFFC0; + calc_type g = (rgb >> 4) & 0xFFC0; + calc_type b = (rgb << 6) & 0xFFC0; + *p = (pixel_type) + ((((r * alpha + cr * cover) >> 2) & 0x3FF00000) | + (((g * alpha + cg * cover) >> 12) & 0x000FFC00) | + ((b * alpha + cb * cover) >> 22) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (b >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 14) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p << 6) & 0xFFC0); + } + }; + + + + //=================================================blender_rgbAAA_gamma + template<class Gamma> class blender_rgbAAA_gamma + { + public: + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + typedef Gamma gamma_type; + + blender_rgbAAA_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = m_gamma->dir((rgb >> 14) & 0xFFC0); + calc_type g = m_gamma->dir((rgb >> 4) & 0xFFC0); + calc_type b = m_gamma->dir((rgb << 6) & 0xFFC0); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 14) & 0x3FF00000) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) | + (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 ) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (b >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 14) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p << 6) & 0xFFC0); + } + private: + const Gamma* m_gamma; + }; + + + //=====================================================blender_bgrAAA + struct blender_bgrAAA + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type bgr = *p; + calc_type b = (bgr >> 14) & 0xFFC0; + calc_type g = (bgr >> 4) & 0xFFC0; + calc_type r = (bgr << 6) & 0xFFC0; + *p = (pixel_type) + (((((cb - b) * alpha + (b << 16)) >> 2) & 0x3FF00000) | + ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) | + (((cr - r) * alpha + (r << 16)) >> 22) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (r >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 6) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p >> 14) & 0xFFC0); + } + }; + + + + //=================================================blender_bgrAAA_pre + struct blender_bgrAAA_pre + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + cover = (cover + 1) << (color_type::base_shift - 8); + pixel_type bgr = *p; + calc_type b = (bgr >> 14) & 0xFFC0; + calc_type g = (bgr >> 4) & 0xFFC0; + calc_type r = (bgr << 6) & 0xFFC0; + *p = (pixel_type) + ((((b * alpha + cb * cover) >> 2) & 0x3FF00000) | + (((g * alpha + cg * cover) >> 12) & 0x000FFC00) | + ((r * alpha + cr * cover) >> 22) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (r >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 6) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p >> 14) & 0xFFC0); + } + }; + + + + //=================================================blender_bgrAAA_gamma + template<class Gamma> class blender_bgrAAA_gamma + { + public: + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + typedef Gamma gamma_type; + + blender_bgrAAA_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type bgr = *p; + calc_type b = m_gamma->dir((bgr >> 14) & 0xFFC0); + calc_type g = m_gamma->dir((bgr >> 4) & 0xFFC0); + calc_type r = m_gamma->dir((bgr << 6) & 0xFFC0); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 14) & 0x3FF00000) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) | + (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 6 ) | 0xC0000000); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 14) | + ((g & 0xFFC0) << 4) | + (r >> 6) | 0xC0000000); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 6) & 0xFFC0, + (p >> 4) & 0xFFC0, + (p >> 14) & 0xFFC0); + } + + private: + const Gamma* m_gamma; + }; + + + + //=====================================================blender_rgbBBA + struct blender_rgbBBA + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = (rgb >> 16) & 0xFFE0; + calc_type g = (rgb >> 5) & 0xFFE0; + calc_type b = (rgb << 6) & 0xFFC0; + *p = (pixel_type) + (((((cr - r) * alpha + (r << 16)) ) & 0xFFE00000) | + ((((cg - g) * alpha + (g << 16)) >> 11) & 0x001FFC00) | + (((cb - b) * alpha + (b << 16)) >> 22)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 16) & 0xFFE0, + (p >> 5) & 0xFFE0, + (p << 6) & 0xFFC0); + } + }; + + + //=================================================blender_rgbBBA_pre + struct blender_rgbBBA_pre + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + cover = (cover + 1) << (color_type::base_shift - 8); + pixel_type rgb = *p; + calc_type r = (rgb >> 16) & 0xFFE0; + calc_type g = (rgb >> 5) & 0xFFE0; + calc_type b = (rgb << 6) & 0xFFC0; + *p = (pixel_type) + ((((r * alpha + cr * cover) ) & 0xFFE00000) | + (((g * alpha + cg * cover) >> 11) & 0x001FFC00) | + ((b * alpha + cb * cover) >> 22)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 16) & 0xFFE0, + (p >> 5) & 0xFFE0, + (p << 6) & 0xFFC0); + } + }; + + + + //=================================================blender_rgbBBA_gamma + template<class Gamma> class blender_rgbBBA_gamma + { + public: + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + typedef Gamma gamma_type; + + blender_rgbBBA_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type rgb = *p; + calc_type r = m_gamma->dir((rgb >> 16) & 0xFFE0); + calc_type g = m_gamma->dir((rgb >> 5) & 0xFFE0); + calc_type b = m_gamma->dir((rgb << 6) & 0xFFC0); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 16) & 0xFFE00000) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 5 ) & 0x001FFC00) | + (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 )); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p >> 16) & 0xFFE0, + (p >> 5) & 0xFFE0, + (p << 6) & 0xFFC0); + } + + private: + const Gamma* m_gamma; + }; + + + //=====================================================blender_bgrABB + struct blender_bgrABB + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type bgr = *p; + calc_type b = (bgr >> 16) & 0xFFC0; + calc_type g = (bgr >> 6) & 0xFFE0; + calc_type r = (bgr << 5) & 0xFFE0; + *p = (pixel_type) + (((((cb - b) * alpha + (b << 16)) ) & 0xFFC00000) | + ((((cg - g) * alpha + (g << 16)) >> 10) & 0x003FF800) | + (((cr - r) * alpha + (r << 16)) >> 21)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 5) & 0xFFE0, + (p >> 6) & 0xFFE0, + (p >> 16) & 0xFFC0); + } + }; + + + //=================================================blender_bgrABB_pre + struct blender_bgrABB_pre + { + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + + static AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned cover) + { + alpha = color_type::base_mask - alpha; + cover = (cover + 1) << (color_type::base_shift - 8); + pixel_type bgr = *p; + calc_type b = (bgr >> 16) & 0xFFC0; + calc_type g = (bgr >> 6) & 0xFFE0; + calc_type r = (bgr << 5) & 0xFFE0; + *p = (pixel_type) + ((((b * alpha + cb * cover) ) & 0xFFC00000) | + (((g * alpha + cg * cover) >> 10) & 0x003FF800) | + ((r * alpha + cr * cover) >> 21)); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 5) & 0xFFE0, + (p >> 6) & 0xFFE0, + (p >> 16) & 0xFFC0); + } + }; + + + + //=================================================blender_bgrABB_gamma + template<class Gamma> class blender_bgrABB_gamma + { + public: + typedef rgba16 color_type; + typedef color_type::value_type value_type; + typedef color_type::calc_type calc_type; + typedef int32u pixel_type; + typedef Gamma gamma_type; + + blender_bgrABB_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + AGG_INLINE void blend_pix(pixel_type* p, + unsigned cr, unsigned cg, unsigned cb, + unsigned alpha, + unsigned) + { + pixel_type bgr = *p; + calc_type b = m_gamma->dir((bgr >> 16) & 0xFFC0); + calc_type g = m_gamma->dir((bgr >> 6) & 0xFFE0); + calc_type r = m_gamma->dir((bgr << 5) & 0xFFE0); + *p = (pixel_type) + (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 16) & 0xFFC00000) | + ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 6 ) & 0x003FF800) | + (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 5 )); + } + + static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b) + { + return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5)); + } + + static AGG_INLINE color_type make_color(pixel_type p) + { + return color_type((p << 5) & 0xFFE0, + (p >> 6) & 0xFFE0, + (p >> 16) & 0xFFC0); + } + + private: + const Gamma* m_gamma; + }; + + + + //===========================================pixfmt_alpha_blend_rgb_packed + template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb_packed + { + public: + typedef RenBuf rbuf_type; + typedef typename rbuf_type::row_data row_data; + typedef Blender blender_type; + typedef typename blender_type::color_type color_type; + typedef typename blender_type::pixel_type pixel_type; + typedef int order_type; // A fake one + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_scale = color_type::base_scale, + base_mask = color_type::base_mask, + pix_width = sizeof(pixel_type), + }; + + private: + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + if (c.a) + { + calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; + if(alpha == base_mask) + { + *p = m_blender.make_pix(c.r, c.g, c.b); + } + else + { + m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); + } + } + } + + public: + //-------------------------------------------------------------------- + explicit pixfmt_alpha_blend_rgb_packed(rbuf_type& rb) : m_rbuf(&rb) {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + + //-------------------------------------------------------------------- + template<class PixFmt> + bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) + { + rect_i r(x1, y1, x2, y2); + if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + { + int stride = pixf.stride(); + m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), + (r.x2 - r.x1) + 1, + (r.y2 - r.y1) + 1, + stride); + return true; + } + return false; + } + + Blender& blender() { return m_blender; } + + //-------------------------------------------------------------------- + AGG_INLINE unsigned width() const { return m_rbuf->width(); } + AGG_INLINE unsigned height() const { return m_rbuf->height(); } + AGG_INLINE int stride() const { return m_rbuf->stride(); } + + //-------------------------------------------------------------------- + AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } + AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } + AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } + + //-------------------------------------------------------------------- + AGG_INLINE int8u* pix_ptr(int x, int y) + { + return m_rbuf->row_ptr(y) + x * pix_width; + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + x * pix_width; + } + + //-------------------------------------------------------------------- + AGG_INLINE void make_pix(int8u* p, const color_type& c) + { + *(pixel_type*)p = m_blender.make_pix(c.r, c.g, c.b); + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + return m_blender.make_color(((pixel_type*)m_rbuf->row_ptr(y))[x]); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + ((pixel_type*) + m_rbuf->row_ptr(x, y, 1))[x] = + m_blender.make_pix(c.r, c.g, c.b); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y, 1) + x, c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x; + pixel_type v = m_blender.make_pix(c.r, c.g, c.b); + do + { + *p++ = v; + } + while(--len); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v = m_blender.make_pix(c.r, c.g, c.b); + do + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x; + *p = v; + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (c.a) + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x; + calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; + if(alpha == base_mask) + { + pixel_type v = m_blender.make_pix(c.r, c.g, c.b); + do + { + *p++ = v; + } + while(--len); + } + else + { + do + { + m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover); + ++p; + } + while(--len); + } + } + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (c.a) + { + calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8; + if(alpha == base_mask) + { + pixel_type v = m_blender.make_pix(c.r, c.g, c.b); + do + { + ((pixel_type*)m_rbuf->row_ptr(x, y++, 1))[x] = v; + } + while(--len); + } + else + { + do + { + m_blender.blend_pix( + (pixel_type*)m_rbuf->row_ptr(x, y++, 1), + c.r, c.g, c.b, alpha, cover); + } + while(--len); + } + } + } + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x; + do + { + copy_or_blend_pix(p, c, *covers++); + ++p; + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + do + { + copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x, + c, *covers++); + } + while(--len); + } + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x; + do + { + *p++ = m_blender.make_pix(colors->r, colors->g, colors->b); + ++colors; + } + while(--len); + } + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + do + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x; + *p = m_blender.make_pix(colors->r, colors->g, colors->b); + ++colors; + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x; + do + { + copy_or_blend_pix(p++, *colors++, covers ? *covers++ : cover); + } + while(--len); + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + do + { + copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x, + *colors++, covers ? *covers++ : cover); + } + while(--len); + } + + //-------------------------------------------------------------------- + template<class RenBuf2> + void copy_from(const RenBuf2& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + const int8u* p = from.row_ptr(ysrc); + if(p) + { + std::memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, + p + xsrc * pix_width, + len * pix_width); + } + } + + //-------------------------------------------------------------------- + template<class SrcPixelFormatRenderer> + void blend_from(const SrcPixelFormatRenderer& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::order_type src_order; + + const value_type* psrc = (const value_type*)from.row_ptr(ysrc); + if(psrc) + { + psrc += xsrc * 4; + pixel_type* pdst = + (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst; + do + { + value_type alpha = psrc[src_order::A]; + if(alpha) + { + if(alpha == base_mask && cover == 255) + { + *pdst = m_blender.make_pix(psrc[src_order::R], + psrc[src_order::G], + psrc[src_order::B]); + } + else + { + m_blender.blend_pix(pdst, + psrc[src_order::R], + psrc[src_order::G], + psrc[src_order::B], + alpha, + cover); + } + } + psrc += 4; + ++pdst; + } + while(--len); + } + } + + //-------------------------------------------------------------------- + template<class SrcPixelFormatRenderer> + void blend_from_color(const SrcPixelFormatRenderer& from, + const color_type& color, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::value_type src_value_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); + if(psrc) + { + psrc += xsrc * SrcPixelFormatRenderer::pix_step + SrcPixelFormatRenderer::pix_offset; + pixel_type* pdst = + (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst; + + do + { + m_blender.blend_pix(pdst, + color.r, color.g, color.b, color.a, + cover); + psrc += SrcPixelFormatRenderer::pix_step; + ++pdst; + } + while(--len); + } + } + + //-------------------------------------------------------------------- + template<class SrcPixelFormatRenderer> + void blend_from_lut(const SrcPixelFormatRenderer& from, + const color_type* color_lut, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::value_type src_value_type; + const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc); + if(psrc) + { + psrc += xsrc * SrcPixelFormatRenderer::pix_step + SrcPixelFormatRenderer::pix_offset; + pixel_type* pdst = + (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst; + + do + { + const color_type& color = color_lut[*psrc]; + m_blender.blend_pix(pdst, + color.r, color.g, color.b, color.a, + cover); + psrc += SrcPixelFormatRenderer::pix_step; + ++pdst; + } + while(--len); + } + } + + + + private: + rbuf_type* m_rbuf; + Blender m_blender; + }; + + typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555, rendering_buffer> pixfmt_rgb555; //----pixfmt_rgb555 + typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565, rendering_buffer> pixfmt_rgb565; //----pixfmt_rgb565 + + typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555_pre, rendering_buffer> pixfmt_rgb555_pre; //----pixfmt_rgb555_pre + typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565_pre, rendering_buffer> pixfmt_rgb565_pre; //----pixfmt_rgb565_pre + + typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA, rendering_buffer> pixfmt_rgbAAA; //----pixfmt_rgbAAA + typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA, rendering_buffer> pixfmt_bgrAAA; //----pixfmt_bgrAAA + typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA, rendering_buffer> pixfmt_rgbBBA; //----pixfmt_rgbBBA + typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB, rendering_buffer> pixfmt_bgrABB; //----pixfmt_bgrABB + + typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_pre, rendering_buffer> pixfmt_rgbAAA_pre; //----pixfmt_rgbAAA_pre + typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_pre, rendering_buffer> pixfmt_bgrAAA_pre; //----pixfmt_bgrAAA_pre + typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_pre, rendering_buffer> pixfmt_rgbBBA_pre; //----pixfmt_rgbBBA_pre + typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB_pre, rendering_buffer> pixfmt_bgrABB_pre; //----pixfmt_bgrABB_pre + + + //-----------------------------------------------------pixfmt_rgb555_gamma + template<class Gamma> class pixfmt_rgb555_gamma : + public pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>, + rendering_buffer> + { + public: + pixfmt_rgb555_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>, + rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + + //-----------------------------------------------------pixfmt_rgb565_gamma + template<class Gamma> class pixfmt_rgb565_gamma : + public pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer> + { + public: + pixfmt_rgb565_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + + //-----------------------------------------------------pixfmt_rgbAAA_gamma + template<class Gamma> class pixfmt_rgbAAA_gamma : + public pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>, + rendering_buffer> + { + public: + pixfmt_rgbAAA_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>, + rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + + //-----------------------------------------------------pixfmt_bgrAAA_gamma + template<class Gamma> class pixfmt_bgrAAA_gamma : + public pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>, + rendering_buffer> + { + public: + pixfmt_bgrAAA_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>, + rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + + //-----------------------------------------------------pixfmt_rgbBBA_gamma + template<class Gamma> class pixfmt_rgbBBA_gamma : + public pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>, + rendering_buffer> + { + public: + pixfmt_rgbBBA_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>, + rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + + //-----------------------------------------------------pixfmt_bgrABB_gamma + template<class Gamma> class pixfmt_bgrABB_gamma : + public pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>, + rendering_buffer> + { + public: + pixfmt_bgrABB_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>, + rendering_buffer>(rb) + { + this->blender().gamma(g); + } + }; + + +} + +#endif + diff --git a/include/agg_pixfmt_rgba.h b/include/agg_pixfmt_rgba.h new file mode 100644 index 0000000..2c7223c --- /dev/null +++ b/include/agg_pixfmt_rgba.h @@ -0,0 +1,2803 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_PIXFMT_RGBA_INCLUDED +#define AGG_PIXFMT_RGBA_INCLUDED + +#include <cstring> +#include <cmath> +#include "agg_pixfmt_base.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + template<class T> inline T sd_min(T a, T b) { return (a < b) ? a : b; } + template<class T> inline T sd_max(T a, T b) { return (a > b) ? a : b; } + + inline rgba & clip(rgba & c) + { + if (c.a > 1) c.a = 1; else if (c.a < 0) c.a = 0; + if (c.r > c.a) c.r = c.a; else if (c.r < 0) c.r = 0; + if (c.g > c.a) c.g = c.a; else if (c.g < 0) c.g = 0; + if (c.b > c.a) c.b = c.a; else if (c.b < 0) c.b = 0; + return c; + } + + //=========================================================multiplier_rgba + template<class ColorT, class Order> + struct multiplier_rgba + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + + //-------------------------------------------------------------------- + static AGG_INLINE void premultiply(value_type* p) + { + value_type a = p[Order::A]; + p[Order::R] = color_type::multiply(p[Order::R], a); + p[Order::G] = color_type::multiply(p[Order::G], a); + p[Order::B] = color_type::multiply(p[Order::B], a); + } + + + //-------------------------------------------------------------------- + static AGG_INLINE void demultiply(value_type* p) + { + value_type a = p[Order::A]; + p[Order::R] = color_type::demultiply(p[Order::R], a); + p[Order::G] = color_type::demultiply(p[Order::G], a); + p[Order::B] = color_type::demultiply(p[Order::B], a); + } + }; + + //=====================================================apply_gamma_dir_rgba + template<class ColorT, class Order, class GammaLut> + class apply_gamma_dir_rgba + { + public: + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + + apply_gamma_dir_rgba(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + p[Order::R] = m_gamma.dir(p[Order::R]); + p[Order::G] = m_gamma.dir(p[Order::G]); + p[Order::B] = m_gamma.dir(p[Order::B]); + } + + private: + const GammaLut& m_gamma; + }; + + //=====================================================apply_gamma_inv_rgba + template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgba + { + public: + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + + apply_gamma_inv_rgba(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + p[Order::R] = m_gamma.inv(p[Order::R]); + p[Order::G] = m_gamma.inv(p[Order::G]); + p[Order::B] = m_gamma.inv(p[Order::B]); + } + + private: + const GammaLut& m_gamma; + }; + + + template<class ColorT, class Order> + struct conv_rgba_pre + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + + //-------------------------------------------------------------------- + static AGG_INLINE void set_plain_color(value_type* p, color_type c) + { + c.premultiply(); + p[Order::R] = c.r; + p[Order::G] = c.g; + p[Order::B] = c.b; + p[Order::A] = c.a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE color_type get_plain_color(const value_type* p) + { + return color_type( + p[Order::R], + p[Order::G], + p[Order::B], + p[Order::A]).demultiply(); + } + }; + + template<class ColorT, class Order> + struct conv_rgba_plain + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + + //-------------------------------------------------------------------- + static AGG_INLINE void set_plain_color(value_type* p, color_type c) + { + p[Order::R] = c.r; + p[Order::G] = c.g; + p[Order::B] = c.b; + p[Order::A] = c.a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE color_type get_plain_color(const value_type* p) + { + return color_type( + p[Order::R], + p[Order::G], + p[Order::B], + p[Order::A]); + } + }; + + //=============================================================blender_rgba + // Blends "plain" (i.e. non-premultiplied) colors into a premultiplied buffer. + template<class ColorT, class Order> + struct blender_rgba : conv_rgba_pre<ColorT, Order> + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. Since the render buffer is in fact premultiplied + // we omit the initial premultiplication and final demultiplication. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + p[Order::R] = color_type::lerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::lerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::lerp(p[Order::B], cb, alpha); + p[Order::A] = color_type::prelerp(p[Order::A], alpha, alpha); + } + }; + + + //========================================================blender_rgba_pre + // Blends premultiplied colors into a premultiplied buffer. + template<class ColorT, class Order> + struct blender_rgba_pre : conv_rgba_pre<ColorT, Order> + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the premultiplied form of Alvy-Ray Smith's + // compositing function. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, + color_type::mult_cover(cr, cover), + color_type::mult_cover(cg, cover), + color_type::mult_cover(cb, cover), + color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha); + p[Order::A] = color_type::prelerp(p[Order::A], alpha, alpha); + } + }; + + //======================================================blender_rgba_plain + // Blends "plain" (non-premultiplied) colors into a plain (non-premultiplied) buffer. + template<class ColorT, class Order> + struct blender_rgba_plain : conv_rgba_plain<ColorT, Order> + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + if (alpha > color_type::empty_value()) + { + calc_type a = p[Order::A]; + calc_type r = color_type::multiply(p[Order::R], a); + calc_type g = color_type::multiply(p[Order::G], a); + calc_type b = color_type::multiply(p[Order::B], a); + p[Order::R] = color_type::lerp(r, cr, alpha); + p[Order::G] = color_type::lerp(g, cg, alpha); + p[Order::B] = color_type::lerp(b, cb, alpha); + p[Order::A] = color_type::prelerp(a, alpha, alpha); + multiplier_rgba<ColorT, Order>::demultiply(p); + } + } + }; + + // SVG compositing operations. + // For specifications, see http://www.w3.org/TR/SVGCompositing/ + + //=========================================================comp_op_rgba_clear + template<class ColorT, class Order> + struct comp_op_rgba_clear : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = 0 + // Da' = 0 + static AGG_INLINE void blend_pix(value_type* p, + value_type, value_type, value_type, value_type, cover_type cover) + { + if (cover >= cover_full) + { + p[0] = p[1] = p[2] = p[3] = color_type::empty_value(); + } + else if (cover > cover_none) + { + set(p, get(p, cover_full - cover)); + } + } + }; + + //===========================================================comp_op_rgba_src + template<class ColorT, class Order> + struct comp_op_rgba_src : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca + // Da' = Sa + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + if (cover >= cover_full) + { + set(p, r, g, b, a); + } + else + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p, cover_full - cover); + d.r += s.r; + d.g += s.g; + d.b += s.b; + d.a += s.a; + set(p, d); + } + } + }; + + //===========================================================comp_op_rgba_dst + template<class ColorT, class Order> + struct comp_op_rgba_dst : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + + // Dca' = Dca.Sa + Dca.(1 - Sa) = Dca + // Da' = Da.Sa + Da.(1 - Sa) = Da + static AGG_INLINE void blend_pix(value_type*, + value_type, value_type, value_type, value_type, cover_type) + { + // Well, that was easy! + } + }; + + //======================================================comp_op_rgba_src_over + template<class ColorT, class Order> + struct comp_op_rgba_src_over : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca + Dca.(1 - Sa) = Dca + Sca - Dca.Sa + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { +#if 1 + blender_rgba_pre<ColorT, Order>::blend_pix(p, r, g, b, a, cover); +#else + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + d.r += s.r - d.r * s.a; + d.g += s.g - d.g * s.a; + d.b += s.b - d.b * s.a; + d.a += s.a - d.a * s.a; + set(p, d); +#endif + } + }; + + //======================================================comp_op_rgba_dst_over + template<class ColorT, class Order> + struct comp_op_rgba_dst_over : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Dca + Sca.(1 - Da) + // Da' = Sa + Da - Sa.Da = Da + Sa.(1 - Da) + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + double d1a = 1 - d.a; + d.r += s.r * d1a; + d.g += s.g * d1a; + d.b += s.b * d1a; + d.a += s.a * d1a; + set(p, d); + } + }; + + //======================================================comp_op_rgba_src_in + template<class ColorT, class Order> + struct comp_op_rgba_src_in : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca.Da + // Da' = Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + double da = ColorT::to_double(p[Order::A]); + if (da > 0) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p, cover_full - cover); + d.r += s.r * da; + d.g += s.g * da; + d.b += s.b * da; + d.a += s.a * da; + set(p, d); + } + } + }; + + //======================================================comp_op_rgba_dst_in + template<class ColorT, class Order> + struct comp_op_rgba_dst_in : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Dca.Sa + // Da' = Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type, value_type, value_type, value_type a, cover_type cover) + { + double sa = ColorT::to_double(a); + rgba d = get(p, cover_full - cover); + rgba d2 = get(p, cover); + d.r += d2.r * sa; + d.g += d2.g * sa; + d.b += d2.b * sa; + d.a += d2.a * sa; + set(p, d); + } + }; + + //======================================================comp_op_rgba_src_out + template<class ColorT, class Order> + struct comp_op_rgba_src_out : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca.(1 - Da) + // Da' = Sa.(1 - Da) + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p, cover_full - cover); + double d1a = 1 - ColorT::to_double(p[Order::A]); + d.r += s.r * d1a; + d.g += s.g * d1a; + d.b += s.b * d1a; + d.a += s.a * d1a; + set(p, d); + } + }; + + //======================================================comp_op_rgba_dst_out + template<class ColorT, class Order> + struct comp_op_rgba_dst_out : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Dca.(1 - Sa) + // Da' = Da.(1 - Sa) + static AGG_INLINE void blend_pix(value_type* p, + value_type, value_type, value_type, value_type a, cover_type cover) + { + rgba d = get(p, cover_full - cover); + rgba dc = get(p, cover); + double s1a = 1 - ColorT::to_double(a); + d.r += dc.r * s1a; + d.g += dc.g * s1a; + d.b += dc.b * s1a; + d.a += dc.a * s1a; + set(p, d); + } + }; + + //=====================================================comp_op_rgba_src_atop + template<class ColorT, class Order> + struct comp_op_rgba_src_atop : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca.Da + Dca.(1 - Sa) + // Da' = Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + double s1a = 1 - s.a; + d.r = s.r * d.a + d.r * s1a; + d.g = s.g * d.a + d.g * s1a; + d.b = s.b * d.a + d.g * s1a; + set(p, d); + } + }; + + //=====================================================comp_op_rgba_dst_atop + template<class ColorT, class Order> + struct comp_op_rgba_dst_atop : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Dca.Sa + Sca.(1 - Da) + // Da' = Sa + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba sc = get(r, g, b, a, cover); + rgba dc = get(p, cover); + rgba d = get(p, cover_full - cover); + double sa = ColorT::to_double(a); + double d1a = 1 - ColorT::to_double(p[Order::A]); + d.r += dc.r * sa + sc.r * d1a; + d.g += dc.g * sa + sc.g * d1a; + d.b += dc.b * sa + sc.b * d1a; + d.a += sc.a; + set(p, d); + } + }; + + //=========================================================comp_op_rgba_xor + template<class ColorT, class Order> + struct comp_op_rgba_xor : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - 2.Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + double s1a = 1 - s.a; + double d1a = 1 - ColorT::to_double(p[Order::A]); + d.r = s.r * d1a + d.r * s1a; + d.g = s.g * d1a + d.g * s1a; + d.b = s.b * d1a + d.b * s1a; + d.a = s.a + d.a - 2 * s.a * d.a; + set(p, d); + } + }; + + //=========================================================comp_op_rgba_plus + template<class ColorT, class Order> + struct comp_op_rgba_plus : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca + Dca + // Da' = Sa + Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + d.a = sd_min(d.a + s.a, 1.0); + d.r = sd_min(d.r + s.r, d.a); + d.g = sd_min(d.g + s.g, d.a); + d.b = sd_min(d.b + s.b, d.a); + set(p, clip(d)); + } + } + }; + + //========================================================comp_op_rgba_minus + // Note: not included in SVG spec. + template<class ColorT, class Order> + struct comp_op_rgba_minus : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Dca - Sca + // Da' = 1 - (1 - Sa).(1 - Da) = Da + Sa - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + d.a += s.a - s.a * d.a; + d.r = sd_max(d.r - s.r, 0.0); + d.g = sd_max(d.g - s.g, 0.0); + d.b = sd_max(d.b - s.b, 0.0); + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_multiply + template<class ColorT, class Order> + struct comp_op_rgba_multiply : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = s.r * d.r + s.r * d1a + d.r * s1a; + d.g = s.g * d.g + s.g * d1a + d.g * s1a; + d.b = s.b * d.b + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_screen + template<class ColorT, class Order> + struct comp_op_rgba_screen : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca + Dca - Sca.Dca + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + d.r += s.r - s.r * d.r; + d.g += s.g - s.g * d.g; + d.b += s.b - s.b * d.b; + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_overlay + template<class ColorT, class Order> + struct comp_op_rgba_overlay : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // if 2.Dca <= Da + // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise + // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + return (2 * dca <= da) ? + 2 * sca * dca + sca * d1a + dca * s1a : + sada - 2 * (da - dca) * (sa - sca) + sca * d1a + dca * s1a; + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + double sada = s.a * d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_darken + template<class ColorT, class Order> + struct comp_op_rgba_darken : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + d.r = sd_min(s.r * d.a, d.r * s.a) + s.r * d1a + d.r * s1a; + d.g = sd_min(s.g * d.a, d.g * s.a) + s.g * d1a + d.g * s1a; + d.b = sd_min(s.b * d.a, d.b * s.a) + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_lighten + template<class ColorT, class Order> + struct comp_op_rgba_lighten : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + d.r = sd_max(s.r * d.a, d.r * s.a) + s.r * d1a + d.r * s1a; + d.g = sd_max(s.g * d.a, d.g * s.a) + s.g * d1a + d.g * s1a; + d.b = sd_max(s.b * d.a, d.b * s.a) + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_color_dodge + template<class ColorT, class Order> + struct comp_op_rgba_color_dodge : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // if Sca == Sa and Dca == 0 + // Dca' = Sca.(1 - Da) + Dca.(1 - Sa) = Sca.(1 - Da) + // otherwise if Sca == Sa + // Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise if Sca < Sa + // Dca' = Sa.Da.min(1, Dca/Da.Sa/(Sa - Sca)) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + if (sca < sa) return sada * sd_min(1.0, (dca / da) * sa / (sa - sca)) + sca * d1a + dca * s1a; + if (dca > 0) return sada + sca * d1a + dca * s1a; + return sca * d1a; + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + if (d.a > 0) + { + double sada = s.a * d.a; + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + else set(p, s); + } + } + }; + + //=====================================================comp_op_rgba_color_burn + template<class ColorT, class Order> + struct comp_op_rgba_color_burn : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // if Sca == 0 and Dca == Da + // Dca' = Sa.Da + Dca.(1 - Sa) + // otherwise if Sca == 0 + // Dca' = Dca.(1 - Sa) + // otherwise if Sca > 0 + // Dca' = Sa.Da.(1 - min(1, (1 - Dca/Da).Sa/Sca)) + Sca.(1 - Da) + Dca.(1 - Sa) + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + if (sca > 0) return sada * (1 - sd_min(1.0, (1 - dca / da) * sa / sca)) + sca * d1a + dca * s1a; + if (dca > da) return sada + dca * s1a; + return dca * s1a; + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + if (d.a > 0) + { + double sada = s.a * d.a; + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - sada; + set(p, clip(d)); + } + else set(p, s); + } + } + }; + + //=====================================================comp_op_rgba_hard_light + template<class ColorT, class Order> + struct comp_op_rgba_hard_light : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // if 2.Sca < Sa + // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise + // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + return (2 * sca < sa) ? + 2 * sca * dca + sca * d1a + dca * s1a : + sada - 2 * (da - dca) * (sa - sca) + sca * d1a + dca * s1a; + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + double sada = s.a * d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - sada; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_soft_light + template<class ColorT, class Order> + struct comp_op_rgba_soft_light : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // if 2.Sca <= Sa + // Dca' = Dca.Sa - (Sa.Da - 2.Sca.Da).Dca.Sa.(Sa.Da - Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise if 2.Sca > Sa and 4.Dca <= Da + // Dca' = Dca.Sa + (2.Sca.Da - Sa.Da).((((16.Dsa.Sa - 12).Dsa.Sa + 4).Dsa.Da) - Dsa.Da) + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise if 2.Sca > Sa and 4.Dca > Da + // Dca' = Dca.Sa + (2.Sca.Da - Sa.Da).((Dca.Sa)^0.5 - Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + double dcasa = dca * sa; + if (2 * sca <= sa) return dcasa - (sada - 2 * sca * da) * dcasa * (sada - dcasa) + sca * d1a + dca * s1a; + if (4 * dca <= da) return dcasa + (2 * sca * da - sada) * ((((16 * dcasa - 12) * dcasa + 4) * dca * da) - dca * da) + sca * d1a + dca * s1a; + return dcasa + (2 * sca * da - sada) * (std::sqrt(dcasa) - dcasa) + sca * d1a + dca * s1a; + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + if (d.a > 0) + { + double sada = s.a * d.a; + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - sada; + set(p, clip(d)); + } + else set(p, s); + } + } + }; + + //=====================================================comp_op_rgba_difference + template<class ColorT, class Order> + struct comp_op_rgba_difference : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca + Dca - 2.min(Sca.Da, Dca.Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + d.r += s.r - 2 * sd_min(s.r * d.a, d.r * s.a); + d.g += s.g - 2 * sd_min(s.g * d.a, d.g * s.a); + d.b += s.b - 2 * sd_min(s.b * d.a, d.b * s.a); + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_exclusion + template<class ColorT, class Order> + struct comp_op_rgba_exclusion : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + d.r = (s.r * d.a + d.r * s.a - 2 * s.r * d.r) + s.r * d1a + d.r * s1a; + d.g = (s.g * d.a + d.g * s.a - 2 * s.g * d.g) + s.g * d1a + d.g * s1a; + d.b = (s.b * d.a + d.b * s.a - 2 * s.b * d.b) + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + +#if 0 + //=====================================================comp_op_rgba_contrast + template<class ColorT, class Order> struct comp_op_rgba_contrast + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + long_type dr = p[Order::R]; + long_type dg = p[Order::G]; + long_type db = p[Order::B]; + int da = p[Order::A]; + long_type d2a = da >> 1; + unsigned s2a = sa >> 1; + + int r = (int)((((dr - d2a) * int((sr - s2a)*2 + base_mask)) >> base_shift) + d2a); + int g = (int)((((dg - d2a) * int((sg - s2a)*2 + base_mask)) >> base_shift) + d2a); + int b = (int)((((db - d2a) * int((sb - s2a)*2 + base_mask)) >> base_shift) + d2a); + + r = (r < 0) ? 0 : r; + g = (g < 0) ? 0 : g; + b = (b < 0) ? 0 : b; + + p[Order::R] = (value_type)((r > da) ? da : r); + p[Order::G] = (value_type)((g > da) ? da : g); + p[Order::B] = (value_type)((b > da) ? da : b); + } + }; + + //=====================================================comp_op_rgba_invert + template<class ColorT, class Order> struct comp_op_rgba_invert + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // Dca' = (Da - Dca) * Sa + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + sa = (sa * cover + 255) >> 8; + if (sa) + { + calc_type da = p[Order::A]; + calc_type dr = ((da - p[Order::R]) * sa + base_mask) >> base_shift; + calc_type dg = ((da - p[Order::G]) * sa + base_mask) >> base_shift; + calc_type db = ((da - p[Order::B]) * sa + base_mask) >> base_shift; + calc_type s1a = base_mask - sa; + p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift)); + p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift)); + p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=================================================comp_op_rgba_invert_rgb + template<class ColorT, class Order> struct comp_op_rgba_invert_rgb + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // Dca' = (Da - Dca) * Sca + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if (sa) + { + calc_type da = p[Order::A]; + calc_type dr = ((da - p[Order::R]) * sr + base_mask) >> base_shift; + calc_type dg = ((da - p[Order::G]) * sg + base_mask) >> base_shift; + calc_type db = ((da - p[Order::B]) * sb + base_mask) >> base_shift; + calc_type s1a = base_mask - sa; + p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift)); + p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift)); + p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; +#endif + + + //======================================================comp_op_table_rgba + template<class ColorT, class Order> struct comp_op_table_rgba + { + typedef typename ColorT::value_type value_type; + typedef typename ColorT::calc_type calc_type; + typedef void (*comp_op_func_type)(value_type* p, + value_type cr, + value_type cg, + value_type cb, + value_type ca, + cover_type cover); + static comp_op_func_type g_comp_op_func[]; + }; + + //==========================================================g_comp_op_func + template<class ColorT, class Order> + typename comp_op_table_rgba<ColorT, Order>::comp_op_func_type + comp_op_table_rgba<ColorT, Order>::g_comp_op_func[] = + { + comp_op_rgba_clear <ColorT,Order>::blend_pix, + comp_op_rgba_src <ColorT,Order>::blend_pix, + comp_op_rgba_dst <ColorT,Order>::blend_pix, + comp_op_rgba_src_over <ColorT,Order>::blend_pix, + comp_op_rgba_dst_over <ColorT,Order>::blend_pix, + comp_op_rgba_src_in <ColorT,Order>::blend_pix, + comp_op_rgba_dst_in <ColorT,Order>::blend_pix, + comp_op_rgba_src_out <ColorT,Order>::blend_pix, + comp_op_rgba_dst_out <ColorT,Order>::blend_pix, + comp_op_rgba_src_atop <ColorT,Order>::blend_pix, + comp_op_rgba_dst_atop <ColorT,Order>::blend_pix, + comp_op_rgba_xor <ColorT,Order>::blend_pix, + comp_op_rgba_plus <ColorT,Order>::blend_pix, + //comp_op_rgba_minus <ColorT,Order>::blend_pix, + comp_op_rgba_multiply <ColorT,Order>::blend_pix, + comp_op_rgba_screen <ColorT,Order>::blend_pix, + comp_op_rgba_overlay <ColorT,Order>::blend_pix, + comp_op_rgba_darken <ColorT,Order>::blend_pix, + comp_op_rgba_lighten <ColorT,Order>::blend_pix, + comp_op_rgba_color_dodge<ColorT,Order>::blend_pix, + comp_op_rgba_color_burn <ColorT,Order>::blend_pix, + comp_op_rgba_hard_light <ColorT,Order>::blend_pix, + comp_op_rgba_soft_light <ColorT,Order>::blend_pix, + comp_op_rgba_difference <ColorT,Order>::blend_pix, + comp_op_rgba_exclusion <ColorT,Order>::blend_pix, + //comp_op_rgba_contrast <ColorT,Order>::blend_pix, + //comp_op_rgba_invert <ColorT,Order>::blend_pix, + //comp_op_rgba_invert_rgb <ColorT,Order>::blend_pix, + 0 + }; + + + //==============================================================comp_op_e + enum comp_op_e + { + comp_op_clear, //----comp_op_clear + comp_op_src, //----comp_op_src + comp_op_dst, //----comp_op_dst + comp_op_src_over, //----comp_op_src_over + comp_op_dst_over, //----comp_op_dst_over + comp_op_src_in, //----comp_op_src_in + comp_op_dst_in, //----comp_op_dst_in + comp_op_src_out, //----comp_op_src_out + comp_op_dst_out, //----comp_op_dst_out + comp_op_src_atop, //----comp_op_src_atop + comp_op_dst_atop, //----comp_op_dst_atop + comp_op_xor, //----comp_op_xor + comp_op_plus, //----comp_op_plus + //comp_op_minus, //----comp_op_minus + comp_op_multiply, //----comp_op_multiply + comp_op_screen, //----comp_op_screen + comp_op_overlay, //----comp_op_overlay + comp_op_darken, //----comp_op_darken + comp_op_lighten, //----comp_op_lighten + comp_op_color_dodge, //----comp_op_color_dodge + comp_op_color_burn, //----comp_op_color_burn + comp_op_hard_light, //----comp_op_hard_light + comp_op_soft_light, //----comp_op_soft_light + comp_op_difference, //----comp_op_difference + comp_op_exclusion, //----comp_op_exclusion + //comp_op_contrast, //----comp_op_contrast + //comp_op_invert, //----comp_op_invert + //comp_op_invert_rgb, //----comp_op_invert_rgb + + end_of_comp_op_e + }; + + + + + + + + //====================================================comp_op_adaptor_rgba + template<class ColorT, class Order> + struct comp_op_adaptor_rgba + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, + color_type::multiply(r, a), + color_type::multiply(g, a), + color_type::multiply(b, a), + a, cover); + } + }; + + //=========================================comp_op_adaptor_clip_to_dst_rgba + template<class ColorT, class Order> + struct comp_op_adaptor_clip_to_dst_rgba + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + r = color_type::multiply(r, a); + g = color_type::multiply(g, a); + b = color_type::multiply(b, a); + value_type da = p[Order::A]; + comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), cover); + } + }; + + //================================================comp_op_adaptor_rgba_pre + template<class ColorT, class Order> + struct comp_op_adaptor_rgba_pre + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, r, g, b, a, cover); + } + }; + + //=====================================comp_op_adaptor_clip_to_dst_rgba_pre + template<class ColorT, class Order> + struct comp_op_adaptor_clip_to_dst_rgba_pre + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + value_type da = p[Order::A]; + comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), cover); + } + }; + + //====================================================comp_op_adaptor_rgba_plain + template<class ColorT, class Order> + struct comp_op_adaptor_rgba_plain + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + multiplier_rgba<ColorT, Order>::premultiply(p); + comp_op_adaptor_rgba<ColorT, Order>::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba<ColorT, Order>::demultiply(p); + } + }; + + //=========================================comp_op_adaptor_clip_to_dst_rgba_plain + template<class ColorT, class Order> + struct comp_op_adaptor_clip_to_dst_rgba_plain + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + multiplier_rgba<ColorT, Order>::premultiply(p); + comp_op_adaptor_clip_to_dst_rgba<ColorT, Order>::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba<ColorT, Order>::demultiply(p); + } + }; + + //=======================================================comp_adaptor_rgba + template<class BlenderPre> + struct comp_adaptor_rgba + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + BlenderPre::blend_pix(p, + color_type::multiply(r, a), + color_type::multiply(g, a), + color_type::multiply(b, a), + a, cover); + } + }; + + //==========================================comp_adaptor_clip_to_dst_rgba + template<class BlenderPre> + struct comp_adaptor_clip_to_dst_rgba + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + r = color_type::multiply(r, a); + g = color_type::multiply(g, a); + b = color_type::multiply(b, a); + value_type da = p[order_type::A]; + BlenderPre::blend_pix(p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), cover); + } + }; + + //=======================================================comp_adaptor_rgba_pre + template<class BlenderPre> + struct comp_adaptor_rgba_pre + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + BlenderPre::blend_pix(p, r, g, b, a, cover); + } + }; + + //======================================comp_adaptor_clip_to_dst_rgba_pre + template<class BlenderPre> + struct comp_adaptor_clip_to_dst_rgba_pre + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + unsigned da = p[order_type::A]; + BlenderPre::blend_pix(p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), + cover); + } + }; + + //=======================================================comp_adaptor_rgba_plain + template<class BlenderPre> + struct comp_adaptor_rgba_plain + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + multiplier_rgba<color_type, order_type>::premultiply(p); + comp_adaptor_rgba<BlenderPre>::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba<color_type, order_type>::demultiply(p); + } + }; + + //==========================================comp_adaptor_clip_to_dst_rgba_plain + template<class BlenderPre> + struct comp_adaptor_clip_to_dst_rgba_plain + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + multiplier_rgba<color_type, order_type>::premultiply(p); + comp_adaptor_clip_to_dst_rgba<BlenderPre>::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba<color_type, order_type>::demultiply(p); + } + }; + + + //=================================================pixfmt_alpha_blend_rgba + template<class Blender, class RenBuf> + class pixfmt_alpha_blend_rgba + { + public: + typedef pixfmt_rgba_tag pixfmt_category; + typedef RenBuf rbuf_type; + typedef typename rbuf_type::row_data row_data; + typedef Blender blender_type; + typedef typename blender_type::color_type color_type; + typedef typename blender_type::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + enum + { + num_components = 4, + pix_step = 4, + pix_width = sizeof(value_type) * pix_step, + }; + struct pixel_type + { + value_type c[num_components]; + + void set(value_type r, value_type g, value_type b, value_type a) + { + c[order_type::R] = r; + c[order_type::G] = g; + c[order_type::B] = b; + c[order_type::A] = a; + } + + void set(const color_type& color) + { + set(color.r, color.g, color.b, color.a); + } + + void get(value_type& r, value_type& g, value_type& b, value_type& a) const + { + r = c[order_type::R]; + g = c[order_type::G]; + b = c[order_type::B]; + a = c[order_type::A]; + } + + color_type get() const + { + return color_type( + c[order_type::R], + c[order_type::G], + c[order_type::B], + c[order_type::A]); + } + + pixel_type* next() + { + return (pixel_type*)(c + pix_step); + } + + const pixel_type* next() const + { + return (const pixel_type*)(c + pix_step); + } + + pixel_type* advance(int n) + { + return (pixel_type*)(c + n * pix_step); + } + + const pixel_type* advance(int n) const + { + return (const pixel_type*)(c + n * pix_step); + } + }; + + private: + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + p->set(c.r, c.g, c.b, c.a); + } + else + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover); + } + } + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c) + { + if (!c.is_transparent()) + { + if (c.is_opaque()) + { + p->set(c.r, c.g, c.b, c.a); + } + else + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a); + } + } + } + + public: + //-------------------------------------------------------------------- + pixfmt_alpha_blend_rgba() : m_rbuf(0) {} + explicit pixfmt_alpha_blend_rgba(rbuf_type& rb) : m_rbuf(&rb) {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + + //-------------------------------------------------------------------- + template<class PixFmt> + bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) + { + rect_i r(x1, y1, x2, y2); + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + { + int stride = pixf.stride(); + m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), + (r.x2 - r.x1) + 1, + (r.y2 - r.y1) + 1, + stride); + return true; + } + return false; + } + + //-------------------------------------------------------------------- + AGG_INLINE unsigned width() const { return m_rbuf->width(); } + AGG_INLINE unsigned height() const { return m_rbuf->height(); } + AGG_INLINE int stride() const { return m_rbuf->stride(); } + + //-------------------------------------------------------------------- + AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } + AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } + AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } + + //-------------------------------------------------------------------- + AGG_INLINE int8u* pix_ptr(int x, int y) + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const + { + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step)) : 0; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)p; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)p; + } + + //-------------------------------------------------------------------- + AGG_INLINE static void write_plain_color(void* p, color_type c) + { + blender_type::set_plain_color(pix_value_ptr(p)->c, c); + } + + //-------------------------------------------------------------------- + AGG_INLINE static color_type read_plain_color(const void* p) + { + return blender_type::get_plain_color(pix_value_ptr(p)->c); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void make_pix(int8u* p, const color_type& c) + { + ((pixel_type*)p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + pix_value_ptr(x, y, 1)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v; + v.set(c); + pixel_type* p = pix_value_ptr(x, y, len); + do + { + *p = v; + p = p->next(); + } + while (--len); + } + + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v; + v.set(c); + do + { + *pix_value_ptr(x, y++, 1) = v; + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + if (c.is_opaque() && cover == cover_mask) + { + pixel_type v; + v.set(c); + do + { + *p = v; + p = p->next(); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + blend_pix(p, c); + p = p->next(); + } + while (--len); + } + else + { + do + { + blend_pix(p, c, cover); + p = p->next(); + } + while (--len); + } + } + } + } + + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + pixel_type v; + v.set(c); + do + { + *pix_value_ptr(x, y++, 1) = v; + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, c.a); + } + while (--len); + } + else + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, cover); + } + while (--len); + } + } + } + } + + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + do + { + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + p = p->next(); + ++covers; + } + while (--len); + } + } + + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + do + { + pixel_type* p = pix_value_ptr(x, y++, 1); + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + ++covers; + } + while (--len); + } + } + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + pixel_type* p = pix_value_ptr(x, y, len); + do + { + p->set(*colors++); + p = p->next(); + } + while (--len); + } + + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + do + { + pix_value_ptr(x, y++, 1)->set(*colors++); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + pixel_type* p = pix_value_ptr(x, y, len); + if (covers) + { + do + { + copy_or_blend_pix(p, *colors++, *covers++); + p = p->next(); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(p, *colors++); + p = p->next(); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(p, *colors++, cover); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + if (covers) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + template<class Function> void for_each_pixel(Function f) + { + for (unsigned y = 0; y < height(); ++y) + { + row_data r = m_rbuf->row(y); + if (r.ptr) + { + unsigned len = r.x2 - r.x1 + 1; + pixel_type* p = pix_value_ptr(r.x1, y, len); + do + { + f(p->c); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + void premultiply() + { + for_each_pixel(multiplier_rgba<color_type, order_type>::premultiply); + } + + //-------------------------------------------------------------------- + void demultiply() + { + for_each_pixel(multiplier_rgba<color_type, order_type>::demultiply); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_rgba<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_rgba<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class RenBuf2> void copy_from(const RenBuf2& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + if (const int8u* p = from.row_ptr(ysrc)) + { + std::memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, + p + xsrc * pix_width, + len * pix_width); + } + } + + //-------------------------------------------------------------------- + // Blend from another RGBA surface. + template<class SrcPixelFormatRenderer> + void blend_from(const SrcPixelFormatRenderer& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + int srcinc = 1; + int dstinc = 1; + + if (xdst > xsrc) + { + psrc = psrc->advance(len - 1); + pdst = pdst->advance(len - 1); + srcinc = -1; + dstinc = -1; + } + + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(pdst, psrc->get()); + psrc = psrc->advance(srcinc); + pdst = pdst->advance(dstinc); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(pdst, psrc->get(), cover); + psrc = psrc->advance(srcinc); + pdst = pdst->advance(dstinc); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + // Combine single color with grayscale surface and blend. + template<class SrcPixelFormatRenderer> + void blend_from_color(const SrcPixelFormatRenderer& from, + const color_type& color, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + copy_or_blend_pix(pdst, color, + src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. + template<class SrcPixelFormatRenderer> + void blend_from_lut(const SrcPixelFormatRenderer& from, + const color_type* color_lut, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(pdst, color_lut[psrc->c[0]]); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + } + + private: + rbuf_type* m_rbuf; + Blender m_blender; + }; + + //================================================pixfmt_custom_blend_rgba + template<class Blender, class RenBuf> class pixfmt_custom_blend_rgba + { + public: + typedef pixfmt_rgba_tag pixfmt_category; + typedef RenBuf rbuf_type; + typedef typename rbuf_type::row_data row_data; + typedef Blender blender_type; + typedef typename blender_type::color_type color_type; + typedef typename blender_type::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + enum + { + num_components = 4, + pix_step = 4, + pix_width = sizeof(value_type) * pix_step, + }; + struct pixel_type + { + value_type c[num_components]; + + void set(value_type r, value_type g, value_type b, value_type a) + { + c[order_type::R] = r; + c[order_type::G] = g; + c[order_type::B] = b; + c[order_type::A] = a; + } + + void set(const color_type& color) + { + set(color.r, color.g, color.b, color.a); + } + + void get(value_type& r, value_type& g, value_type& b, value_type& a) const + { + r = c[order_type::R]; + g = c[order_type::G]; + b = c[order_type::B]; + a = c[order_type::A]; + } + + color_type get() const + { + return color_type( + c[order_type::R], + c[order_type::G], + c[order_type::B], + c[order_type::A]); + } + + pixel_type* next() + { + return (pixel_type*)(c + pix_step); + } + + const pixel_type* next() const + { + return (const pixel_type*)(c + pix_step); + } + + pixel_type* advance(int n) + { + return (pixel_type*)(c + n * pix_step); + } + + const pixel_type* advance(int n) const + { + return (const pixel_type*)(c + n * pix_step); + } + }; + + + private: + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover = cover_full) + { + m_blender.blend_pix(m_comp_op, p->c, c.r, c.g, c.b, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover = cover_full) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + p->set(c.r, c.g, c.b, c.a); + } + else + { + blend_pix(p, c, cover); + } + } + } + + public: + //-------------------------------------------------------------------- + pixfmt_custom_blend_rgba() : m_rbuf(0), m_comp_op(3) {} + explicit pixfmt_custom_blend_rgba(rbuf_type& rb, unsigned comp_op=3) : + m_rbuf(&rb), + m_comp_op(comp_op) + {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + + //-------------------------------------------------------------------- + template<class PixFmt> + bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) + { + rect_i r(x1, y1, x2, y2); + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + { + int stride = pixf.stride(); + m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), + (r.x2 - r.x1) + 1, + (r.y2 - r.y1) + 1, + stride); + return true; + } + return false; + } + + //-------------------------------------------------------------------- + void comp_op(unsigned op) { m_comp_op = op; } + unsigned comp_op() const { return m_comp_op; } + + //-------------------------------------------------------------------- + AGG_INLINE unsigned width() const { return m_rbuf->width(); } + AGG_INLINE unsigned height() const { return m_rbuf->height(); } + AGG_INLINE int stride() const { return m_rbuf->stride(); } + + //-------------------------------------------------------------------- + AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } + AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } + AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); } + + //-------------------------------------------------------------------- + AGG_INLINE int8u* pix_ptr(int x, int y) + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const + { + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step)) : 0; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)p; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)p; + } + + //-------------------------------------------------------------------- + AGG_INLINE static void make_pix(int8u* p, const color_type& c) + { + ((pixel_type*)p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + pix_value_ptr(x, y, 1)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + blend_pix(pix_value_ptr(x, y, 1), c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v; + v.set(c); + pixel_type* p = pix_value_ptr(x, y, len); + do + { + *p = v; + p = p->next(); + } + while (--len); + } + + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v; + v.set(c); + do + { + *pix_value_ptr(x, y++, 1) = v; + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, unsigned len, + const color_type& c, int8u cover) + { + + pixel_type* p = pix_value_ptr(x, y, len); + do + { + blend_pix(p, c, cover); + p = p->next(); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, unsigned len, + const color_type& c, int8u cover) + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, cover); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, unsigned len, + const color_type& c, const int8u* covers) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + blend_pix(p, c, *covers++); + p = p->next(); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, unsigned len, + const color_type& c, const int8u* covers) + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, *covers++); + } + while (--len); + } + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + p->set(*colors++); + p = p->next(); + } + while (--len); + } + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + do + { + pix_value_ptr(x, y++, 1)->set(*colors++); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + blend_pix(p, *colors++, covers ? *covers++ : cover); + p = p->next(); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), *colors++, covers ? *covers++ : cover); + } + while (--len); + + } + + //-------------------------------------------------------------------- + template<class Function> void for_each_pixel(Function f) + { + unsigned y; + for (y = 0; y < height(); ++y) + { + row_data r = m_rbuf->row(y); + if (r.ptr) + { + unsigned len = r.x2 - r.x1 + 1; + pixel_type* p = pix_value_ptr(r.x1, y, len); + do + { + f(p->c); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + void premultiply() + { + for_each_pixel(multiplier_rgba<color_type, order_type>::premultiply); + } + + //-------------------------------------------------------------------- + void demultiply() + { + for_each_pixel(multiplier_rgba<color_type, order_type>::demultiply); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_rgba<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_rgba<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class RenBuf2> void copy_from(const RenBuf2& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + if (const int8u* p = from.row_ptr(ysrc)) + { + std::memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, + p + xsrc * pix_width, + len * pix_width); + } + } + + //-------------------------------------------------------------------- + // Blend from another RGBA surface. + template<class SrcPixelFormatRenderer> + void blend_from(const SrcPixelFormatRenderer& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + int srcinc = 1; + int dstinc = 1; + + if (xdst > xsrc) + { + psrc = psrc->advance(len - 1); + pdst = pdst->advance(len - 1); + srcinc = -1; + dstinc = -1; + } + + do + { + blend_pix(pdst, psrc->get(), cover); + psrc = psrc->advance(srcinc); + pdst = pdst->advance(dstinc); + } + while (--len); + } + } + + //-------------------------------------------------------------------- + // Blend from single color, using grayscale surface as alpha channel. + template<class SrcPixelFormatRenderer> + void blend_from_color(const SrcPixelFormatRenderer& from, + const color_type& color, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + blend_pix(pdst, color, + src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. + template<class SrcPixelFormatRenderer> + void blend_from_lut(const SrcPixelFormatRenderer& from, + const color_type* color_lut, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + private: + rbuf_type* m_rbuf; + Blender m_blender; + unsigned m_comp_op; + }; + + + //----------------------------------------------------------------------- + typedef blender_rgba<rgba8, order_rgba> blender_rgba32; + typedef blender_rgba<rgba8, order_argb> blender_argb32; + typedef blender_rgba<rgba8, order_abgr> blender_abgr32; + typedef blender_rgba<rgba8, order_bgra> blender_bgra32; + + typedef blender_rgba<srgba8, order_rgba> blender_srgba32; + typedef blender_rgba<srgba8, order_argb> blender_sargb32; + typedef blender_rgba<srgba8, order_abgr> blender_sabgr32; + typedef blender_rgba<srgba8, order_bgra> blender_sbgra32; + + typedef blender_rgba_pre<rgba8, order_rgba> blender_rgba32_pre; + typedef blender_rgba_pre<rgba8, order_argb> blender_argb32_pre; + typedef blender_rgba_pre<rgba8, order_abgr> blender_abgr32_pre; + typedef blender_rgba_pre<rgba8, order_bgra> blender_bgra32_pre; + + typedef blender_rgba_pre<srgba8, order_rgba> blender_srgba32_pre; + typedef blender_rgba_pre<srgba8, order_argb> blender_sargb32_pre; + typedef blender_rgba_pre<srgba8, order_abgr> blender_sabgr32_pre; + typedef blender_rgba_pre<srgba8, order_bgra> blender_sbgra32_pre; + + typedef blender_rgba_plain<rgba8, order_rgba> blender_rgba32_plain; + typedef blender_rgba_plain<rgba8, order_argb> blender_argb32_plain; + typedef blender_rgba_plain<rgba8, order_abgr> blender_abgr32_plain; + typedef blender_rgba_plain<rgba8, order_bgra> blender_bgra32_plain; + + typedef blender_rgba_plain<srgba8, order_rgba> blender_srgba32_plain; + typedef blender_rgba_plain<srgba8, order_argb> blender_sargb32_plain; + typedef blender_rgba_plain<srgba8, order_abgr> blender_sabgr32_plain; + typedef blender_rgba_plain<srgba8, order_bgra> blender_sbgra32_plain; + + typedef blender_rgba<rgba16, order_rgba> blender_rgba64; + typedef blender_rgba<rgba16, order_argb> blender_argb64; + typedef blender_rgba<rgba16, order_abgr> blender_abgr64; + typedef blender_rgba<rgba16, order_bgra> blender_bgra64; + + typedef blender_rgba_pre<rgba16, order_rgba> blender_rgba64_pre; + typedef blender_rgba_pre<rgba16, order_argb> blender_argb64_pre; + typedef blender_rgba_pre<rgba16, order_abgr> blender_abgr64_pre; + typedef blender_rgba_pre<rgba16, order_bgra> blender_bgra64_pre; + + typedef blender_rgba_plain<rgba16, order_rgba> blender_rgba64_plain; + typedef blender_rgba_plain<rgba16, order_argb> blender_argb64_plain; + typedef blender_rgba_plain<rgba16, order_abgr> blender_abgr64_plain; + typedef blender_rgba_plain<rgba16, order_bgra> blender_bgra64_plain; + + typedef blender_rgba<rgba32, order_rgba> blender_rgba128; + typedef blender_rgba<rgba32, order_argb> blender_argb128; + typedef blender_rgba<rgba32, order_abgr> blender_abgr128; + typedef blender_rgba<rgba32, order_bgra> blender_bgra128; + + typedef blender_rgba_pre<rgba32, order_rgba> blender_rgba128_pre; + typedef blender_rgba_pre<rgba32, order_argb> blender_argb128_pre; + typedef blender_rgba_pre<rgba32, order_abgr> blender_abgr128_pre; + typedef blender_rgba_pre<rgba32, order_bgra> blender_bgra128_pre; + + typedef blender_rgba_plain<rgba32, order_rgba> blender_rgba128_plain; + typedef blender_rgba_plain<rgba32, order_argb> blender_argb128_plain; + typedef blender_rgba_plain<rgba32, order_abgr> blender_abgr128_plain; + typedef blender_rgba_plain<rgba32, order_bgra> blender_bgra128_plain; + + + //----------------------------------------------------------------------- + typedef pixfmt_alpha_blend_rgba<blender_rgba32, rendering_buffer> pixfmt_rgba32; + typedef pixfmt_alpha_blend_rgba<blender_argb32, rendering_buffer> pixfmt_argb32; + typedef pixfmt_alpha_blend_rgba<blender_abgr32, rendering_buffer> pixfmt_abgr32; + typedef pixfmt_alpha_blend_rgba<blender_bgra32, rendering_buffer> pixfmt_bgra32; + + typedef pixfmt_alpha_blend_rgba<blender_srgba32, rendering_buffer> pixfmt_srgba32; + typedef pixfmt_alpha_blend_rgba<blender_sargb32, rendering_buffer> pixfmt_sargb32; + typedef pixfmt_alpha_blend_rgba<blender_sabgr32, rendering_buffer> pixfmt_sabgr32; + typedef pixfmt_alpha_blend_rgba<blender_sbgra32, rendering_buffer> pixfmt_sbgra32; + + typedef pixfmt_alpha_blend_rgba<blender_rgba32_pre, rendering_buffer> pixfmt_rgba32_pre; + typedef pixfmt_alpha_blend_rgba<blender_argb32_pre, rendering_buffer> pixfmt_argb32_pre; + typedef pixfmt_alpha_blend_rgba<blender_abgr32_pre, rendering_buffer> pixfmt_abgr32_pre; + typedef pixfmt_alpha_blend_rgba<blender_bgra32_pre, rendering_buffer> pixfmt_bgra32_pre; + + typedef pixfmt_alpha_blend_rgba<blender_srgba32_pre, rendering_buffer> pixfmt_srgba32_pre; + typedef pixfmt_alpha_blend_rgba<blender_sargb32_pre, rendering_buffer> pixfmt_sargb32_pre; + typedef pixfmt_alpha_blend_rgba<blender_sabgr32_pre, rendering_buffer> pixfmt_sabgr32_pre; + typedef pixfmt_alpha_blend_rgba<blender_sbgra32_pre, rendering_buffer> pixfmt_sbgra32_pre; + + typedef pixfmt_alpha_blend_rgba<blender_rgba32_plain, rendering_buffer> pixfmt_rgba32_plain; + typedef pixfmt_alpha_blend_rgba<blender_argb32_plain, rendering_buffer> pixfmt_argb32_plain; + typedef pixfmt_alpha_blend_rgba<blender_abgr32_plain, rendering_buffer> pixfmt_abgr32_plain; + typedef pixfmt_alpha_blend_rgba<blender_bgra32_plain, rendering_buffer> pixfmt_bgra32_plain; + + typedef pixfmt_alpha_blend_rgba<blender_srgba32_plain, rendering_buffer> pixfmt_srgba32_plain; + typedef pixfmt_alpha_blend_rgba<blender_sargb32_plain, rendering_buffer> pixfmt_sargb32_plain; + typedef pixfmt_alpha_blend_rgba<blender_sabgr32_plain, rendering_buffer> pixfmt_sabgr32_plain; + typedef pixfmt_alpha_blend_rgba<blender_sbgra32_plain, rendering_buffer> pixfmt_sbgra32_plain; + + typedef pixfmt_alpha_blend_rgba<blender_rgba64, rendering_buffer> pixfmt_rgba64; + typedef pixfmt_alpha_blend_rgba<blender_argb64, rendering_buffer> pixfmt_argb64; + typedef pixfmt_alpha_blend_rgba<blender_abgr64, rendering_buffer> pixfmt_abgr64; + typedef pixfmt_alpha_blend_rgba<blender_bgra64, rendering_buffer> pixfmt_bgra64; + + typedef pixfmt_alpha_blend_rgba<blender_rgba64_pre, rendering_buffer> pixfmt_rgba64_pre; + typedef pixfmt_alpha_blend_rgba<blender_argb64_pre, rendering_buffer> pixfmt_argb64_pre; + typedef pixfmt_alpha_blend_rgba<blender_abgr64_pre, rendering_buffer> pixfmt_abgr64_pre; + typedef pixfmt_alpha_blend_rgba<blender_bgra64_pre, rendering_buffer> pixfmt_bgra64_pre; + + typedef pixfmt_alpha_blend_rgba<blender_rgba64_plain, rendering_buffer> pixfmt_rgba64_plain; + typedef pixfmt_alpha_blend_rgba<blender_argb64_plain, rendering_buffer> pixfmt_argb64_plain; + typedef pixfmt_alpha_blend_rgba<blender_abgr64_plain, rendering_buffer> pixfmt_abgr64_plain; + typedef pixfmt_alpha_blend_rgba<blender_bgra64_plain, rendering_buffer> pixfmt_bgra64_plain; + + typedef pixfmt_alpha_blend_rgba<blender_rgba128, rendering_buffer> pixfmt_rgba128; + typedef pixfmt_alpha_blend_rgba<blender_argb128, rendering_buffer> pixfmt_argb128; + typedef pixfmt_alpha_blend_rgba<blender_abgr128, rendering_buffer> pixfmt_abgr128; + typedef pixfmt_alpha_blend_rgba<blender_bgra128, rendering_buffer> pixfmt_bgra128; + + typedef pixfmt_alpha_blend_rgba<blender_rgba128_pre, rendering_buffer> pixfmt_rgba128_pre; + typedef pixfmt_alpha_blend_rgba<blender_argb128_pre, rendering_buffer> pixfmt_argb128_pre; + typedef pixfmt_alpha_blend_rgba<blender_abgr128_pre, rendering_buffer> pixfmt_abgr128_pre; + typedef pixfmt_alpha_blend_rgba<blender_bgra128_pre, rendering_buffer> pixfmt_bgra128_pre; + + typedef pixfmt_alpha_blend_rgba<blender_rgba128_plain, rendering_buffer> pixfmt_rgba128_plain; + typedef pixfmt_alpha_blend_rgba<blender_argb128_plain, rendering_buffer> pixfmt_argb128_plain; + typedef pixfmt_alpha_blend_rgba<blender_abgr128_plain, rendering_buffer> pixfmt_abgr128_plain; + typedef pixfmt_alpha_blend_rgba<blender_bgra128_plain, rendering_buffer> pixfmt_bgra128_plain; + +} + +#endif + diff --git a/include/agg_pixfmt_transposer.h b/include/agg_pixfmt_transposer.h new file mode 100644 index 0000000..64738b6 --- /dev/null +++ b/include/agg_pixfmt_transposer.h @@ -0,0 +1,157 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_PIXFMT_TRANSPOSER_INCLUDED +#define AGG_PIXFMT_TRANSPOSER_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //=======================================================pixfmt_transposer + template<class PixFmt> class pixfmt_transposer + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::row_data row_data; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + + //-------------------------------------------------------------------- + pixfmt_transposer() : m_pixf(0) {} + explicit pixfmt_transposer(pixfmt_type& pixf) : m_pixf(&pixf) {} + void attach(pixfmt_type& pixf) { m_pixf = &pixf; } + + //-------------------------------------------------------------------- + AGG_INLINE unsigned width() const { return m_pixf->height(); } + AGG_INLINE unsigned height() const { return m_pixf->width(); } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + return m_pixf->pixel(y, x); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + m_pixf->copy_pixel(y, x, c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, + const color_type& c, + int8u cover) + { + m_pixf->blend_pixel(y, x, c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + m_pixf->copy_vline(y, x, len, c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + m_pixf->copy_hline(y, x, len, c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_hline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + m_pixf->blend_vline(y, x, len, c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_vline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + m_pixf->blend_hline(y, x, len, c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_solid_hspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + m_pixf->blend_solid_vspan(y, x, len, c, covers); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + m_pixf->blend_solid_hspan(y, x, len, c, covers); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + m_pixf->copy_color_vspan(y, x, len, colors); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + m_pixf->copy_color_hspan(y, x, len, colors); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_color_hspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + m_pixf->blend_color_vspan(y, x, len, colors, covers, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_color_vspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + m_pixf->blend_color_hspan(y, x, len, colors, covers, cover); + } + + private: + pixfmt_type* m_pixf; + }; +} + +#endif + + diff --git a/include/agg_rasterizer_cells_aa.h b/include/agg_rasterizer_cells_aa.h new file mode 100644 index 0000000..4dd905f --- /dev/null +++ b/include/agg_rasterizer_cells_aa.h @@ -0,0 +1,742 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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. +// +//---------------------------------------------------------------------------- +// +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// libray - in producing this work. See http://www.freetype.org for details. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED +#define AGG_RASTERIZER_CELLS_AA_INCLUDED + +#include <cstring> +#include <cstdlib> +#include <limits> +#include "agg_math.h" +#include "agg_array.h" + + +namespace agg +{ + + //-----------------------------------------------------rasterizer_cells_aa + // An internal class that implements the main rasterization algorithm. + // Used in the rasterizer. Should not be used direcly. + template<class Cell> class rasterizer_cells_aa + { + enum cell_block_scale_e + { + cell_block_shift = 12, + cell_block_size = 1 << cell_block_shift, + cell_block_mask = cell_block_size - 1, + cell_block_pool = 256 + }; + + struct sorted_y + { + unsigned start; + unsigned num; + }; + + public: + typedef Cell cell_type; + typedef rasterizer_cells_aa<Cell> self_type; + + ~rasterizer_cells_aa(); + rasterizer_cells_aa(unsigned cell_block_limit=1024); + + void reset(); + void style(const cell_type& style_cell); + void line(int x1, int y1, int x2, int y2); + + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + void sort_cells(); + + unsigned total_cells() const + { + return m_num_cells; + } + + unsigned scanline_num_cells(unsigned y) const + { + return m_sorted_y[y - m_min_y].num; + } + + const cell_type* const* scanline_cells(unsigned y) const + { + return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start; + } + + bool sorted() const { return m_sorted; } + + private: + rasterizer_cells_aa(const self_type&); + const self_type& operator = (const self_type&); + + void set_curr_cell(int x, int y); + void add_curr_cell(); + void render_hline(int ey, int x1, int y1, int x2, int y2); + void allocate_block(); + + private: + unsigned m_num_blocks; + unsigned m_max_blocks; + unsigned m_curr_block; + unsigned m_num_cells; + unsigned m_cell_block_limit; + cell_type** m_cells; + cell_type* m_curr_cell_ptr; + pod_vector<cell_type*> m_sorted_cells; + pod_vector<sorted_y> m_sorted_y; + cell_type m_curr_cell; + cell_type m_style_cell; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + bool m_sorted; + }; + + + + + //------------------------------------------------------------------------ + template<class Cell> + rasterizer_cells_aa<Cell>::~rasterizer_cells_aa() + { + if(m_num_blocks) + { + cell_type** ptr = m_cells + m_num_blocks - 1; + while(m_num_blocks--) + { + pod_allocator<cell_type>::deallocate(*ptr, cell_block_size); + ptr--; + } + pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks); + } + } + + //------------------------------------------------------------------------ + template<class Cell> + rasterizer_cells_aa<Cell>::rasterizer_cells_aa(unsigned cell_block_limit) : + m_num_blocks(0), + m_max_blocks(0), + m_curr_block(0), + m_num_cells(0), + m_cell_block_limit(cell_block_limit), + m_cells(0), + m_curr_cell_ptr(0), + m_sorted_cells(), + m_sorted_y(), + m_min_x(std::numeric_limits<int>::max()), + m_min_y(std::numeric_limits<int>::max()), + m_max_x(std::numeric_limits<int>::min()), + m_max_y(std::numeric_limits<int>::min()), + m_sorted(false) + { + m_style_cell.initial(); + m_curr_cell.initial(); + } + + //------------------------------------------------------------------------ + template<class Cell> + void rasterizer_cells_aa<Cell>::reset() + { + m_num_cells = 0; + m_curr_block = 0; + m_curr_cell.initial(); + m_style_cell.initial(); + m_sorted = false; + m_min_x = std::numeric_limits<int>::max(); + m_min_y = std::numeric_limits<int>::max(); + m_max_x = std::numeric_limits<int>::min(); + m_max_y = std::numeric_limits<int>::min(); + } + + //------------------------------------------------------------------------ + template<class Cell> + AGG_INLINE void rasterizer_cells_aa<Cell>::add_curr_cell() + { + if(m_curr_cell.area | m_curr_cell.cover) + { + if((m_num_cells & cell_block_mask) == 0) + { + if(m_num_blocks >= m_cell_block_limit) return; + allocate_block(); + } + *m_curr_cell_ptr++ = m_curr_cell; + ++m_num_cells; + } + } + + //------------------------------------------------------------------------ + template<class Cell> + AGG_INLINE void rasterizer_cells_aa<Cell>::set_curr_cell(int x, int y) + { + if(m_curr_cell.not_equal(x, y, m_style_cell)) + { + add_curr_cell(); + m_curr_cell.style(m_style_cell); + m_curr_cell.x = x; + m_curr_cell.y = y; + m_curr_cell.cover = 0; + m_curr_cell.area = 0; + } + } + + //------------------------------------------------------------------------ + template<class Cell> + AGG_INLINE void rasterizer_cells_aa<Cell>::render_hline(int ey, + int x1, int y1, + int x2, int y2) + { + int ex1 = x1 >> poly_subpixel_shift; + int ex2 = x2 >> poly_subpixel_shift; + int fx1 = x1 & poly_subpixel_mask; + int fx2 = x2 & poly_subpixel_mask; + + int delta, p, first; + long long dx; + int incr, lift, mod, rem; + + //trivial case. Happens often + if(y1 == y2) + { + set_curr_cell(ex2, ey); + return; + } + + //everything is located in a single cell. That is easy! + if(ex1 == ex2) + { + delta = y2 - y1; + m_curr_cell.cover += delta; + m_curr_cell.area += (fx1 + fx2) * delta; + return; + } + + //ok, we'll have to render a run of adjacent cells on the same + //hline... + p = (poly_subpixel_scale - fx1) * (y2 - y1); + first = poly_subpixel_scale; + incr = 1; + + dx = (long long)x2 - (long long)x1; + + if(dx < 0) + { + p = fx1 * (y2 - y1); + first = 0; + incr = -1; + dx = -dx; + } + + delta = (int)(p / dx); + mod = (int)(p % dx); + + if(mod < 0) + { + delta--; + mod += dx; + } + + m_curr_cell.cover += delta; + m_curr_cell.area += (fx1 + first) * delta; + + ex1 += incr; + set_curr_cell(ex1, ey); + y1 += delta; + + if(ex1 != ex2) + { + p = poly_subpixel_scale * (y2 - y1 + delta); + lift = (int)(p / dx); + rem = (int)(p % dx); + + if (rem < 0) + { + lift--; + rem += dx; + } + + mod -= dx; + + while (ex1 != ex2) + { + delta = lift; + mod += rem; + if(mod >= 0) + { + mod -= dx; + delta++; + } + + m_curr_cell.cover += delta; + m_curr_cell.area += poly_subpixel_scale * delta; + y1 += delta; + ex1 += incr; + set_curr_cell(ex1, ey); + } + } + delta = y2 - y1; + m_curr_cell.cover += delta; + m_curr_cell.area += (fx2 + poly_subpixel_scale - first) * delta; + } + + //------------------------------------------------------------------------ + template<class Cell> + AGG_INLINE void rasterizer_cells_aa<Cell>::style(const cell_type& style_cell) + { + m_style_cell.style(style_cell); + } + + //------------------------------------------------------------------------ + template<class Cell> + void rasterizer_cells_aa<Cell>::line(int x1, int y1, int x2, int y2) + { + enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift }; + + long long dx = (long long)x2 - (long long)x1; + + if(dx >= dx_limit || dx <= -dx_limit) + { + int cx = (int)(((long long)x1 + (long long)x2) >> 1); + int cy = (int)(((long long)y1 + (long long)y2) >> 1); + line(x1, y1, cx, cy); + line(cx, cy, x2, y2); + } + + long long dy = (long long)y2 - (long long)y1; + int ex1 = x1 >> poly_subpixel_shift; + int ex2 = x2 >> poly_subpixel_shift; + int ey1 = y1 >> poly_subpixel_shift; + int ey2 = y2 >> poly_subpixel_shift; + int fy1 = y1 & poly_subpixel_mask; + int fy2 = y2 & poly_subpixel_mask; + + int x_from, x_to; + int rem, mod, lift, delta, first, incr; + long long p; + + if(ex1 < m_min_x) m_min_x = ex1; + if(ex1 > m_max_x) m_max_x = ex1; + if(ey1 < m_min_y) m_min_y = ey1; + if(ey1 > m_max_y) m_max_y = ey1; + if(ex2 < m_min_x) m_min_x = ex2; + if(ex2 > m_max_x) m_max_x = ex2; + if(ey2 < m_min_y) m_min_y = ey2; + if(ey2 > m_max_y) m_max_y = ey2; + + set_curr_cell(ex1, ey1); + + //everything is on a single hline + if(ey1 == ey2) + { + render_hline(ey1, x1, fy1, x2, fy2); + return; + } + + //Vertical line - we have to calculate start and end cells, + //and then - the common values of the area and coverage for + //all cells of the line. We know exactly there's only one + //cell, so, we don't have to call render_hline(). + incr = 1; + if(dx == 0) + { + int ex = x1 >> poly_subpixel_shift; + int two_fx = (x1 - (ex << poly_subpixel_shift)) << 1; + int area; + + first = poly_subpixel_scale; + if(dy < 0) + { + first = 0; + incr = -1; + } + + x_from = x1; + + //render_hline(ey1, x_from, fy1, x_from, first); + delta = first - fy1; + m_curr_cell.cover += delta; + m_curr_cell.area += two_fx * delta; + + ey1 += incr; + set_curr_cell(ex, ey1); + + delta = first + first - poly_subpixel_scale; + area = two_fx * delta; + while(ey1 != ey2) + { + //render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, first); + m_curr_cell.cover = delta; + m_curr_cell.area = area; + ey1 += incr; + set_curr_cell(ex, ey1); + } + //render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, fy2); + delta = fy2 - poly_subpixel_scale + first; + m_curr_cell.cover += delta; + m_curr_cell.area += two_fx * delta; + return; + } + + //ok, we have to render several hlines + p = (poly_subpixel_scale - fy1) * dx; + first = poly_subpixel_scale; + + if(dy < 0) + { + p = fy1 * dx; + first = 0; + incr = -1; + dy = -dy; + } + + delta = (int)(p / dy); + mod = (int)(p % dy); + + if(mod < 0) + { + delta--; + mod += dy; + } + + x_from = x1 + delta; + render_hline(ey1, x1, fy1, x_from, first); + + ey1 += incr; + set_curr_cell(x_from >> poly_subpixel_shift, ey1); + + if(ey1 != ey2) + { + p = poly_subpixel_scale * dx; + lift = (int)(p / dy); + rem = (int)(p % dy); + + if(rem < 0) + { + lift--; + rem += dy; + } + mod -= dy; + + while(ey1 != ey2) + { + delta = lift; + mod += rem; + if (mod >= 0) + { + mod -= dy; + delta++; + } + + x_to = x_from + delta; + render_hline(ey1, x_from, poly_subpixel_scale - first, x_to, first); + x_from = x_to; + + ey1 += incr; + set_curr_cell(x_from >> poly_subpixel_shift, ey1); + } + } + render_hline(ey1, x_from, poly_subpixel_scale - first, x2, fy2); + } + + //------------------------------------------------------------------------ + template<class Cell> + void rasterizer_cells_aa<Cell>::allocate_block() + { + if(m_curr_block >= m_num_blocks) + { + if(m_num_blocks >= m_max_blocks) + { + cell_type** new_cells = + pod_allocator<cell_type*>::allocate(m_max_blocks + + cell_block_pool); + + if(m_cells) + { + std::memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_type*)); + pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks); + } + m_cells = new_cells; + m_max_blocks += cell_block_pool; + } + + m_cells[m_num_blocks++] = + pod_allocator<cell_type>::allocate(cell_block_size); + + } + m_curr_cell_ptr = m_cells[m_curr_block++]; + } + + + + //------------------------------------------------------------------------ + template <class T> static AGG_INLINE void swap_cells(T* a, T* b) + { + T temp = *a; + *a = *b; + *b = temp; + } + + + //------------------------------------------------------------------------ + enum + { + qsort_threshold = 9 + }; + + + //------------------------------------------------------------------------ + template<class Cell> + void qsort_cells(Cell** start, unsigned num) + { + Cell** stack[80]; + Cell*** top; + Cell** limit; + Cell** base; + + limit = start + num; + base = start; + top = stack; + + for (;;) + { + int len = int(limit - base); + + Cell** i; + Cell** j; + Cell** pivot; + + if(len > qsort_threshold) + { + // we use base + len/2 as the pivot + pivot = base + len / 2; + swap_cells(base, pivot); + + i = base + 1; + j = limit - 1; + + // now ensure that *i <= *base <= *j + if((*j)->x < (*i)->x) + { + swap_cells(i, j); + } + + if((*base)->x < (*i)->x) + { + swap_cells(base, i); + } + + if((*j)->x < (*base)->x) + { + swap_cells(base, j); + } + + for(;;) + { + int x = (*base)->x; + do i++; while( (*i)->x < x ); + do j--; while( x < (*j)->x ); + + if(i > j) + { + break; + } + + swap_cells(i, j); + } + + swap_cells(base, j); + + // now, push the largest sub-array + if(j - base > limit - i) + { + top[0] = base; + top[1] = j; + base = i; + } + else + { + top[0] = i; + top[1] = limit; + limit = j; + } + top += 2; + } + else + { + // the sub-array is small, perform insertion sort + j = base; + i = j + 1; + + for(; i < limit; j = i, i++) + { + for(; j[1]->x < (*j)->x; j--) + { + swap_cells(j + 1, j); + if (j == base) + { + break; + } + } + } + + if(top > stack) + { + top -= 2; + base = top[0]; + limit = top[1]; + } + else + { + break; + } + } + } + } + + + //------------------------------------------------------------------------ + template<class Cell> + void rasterizer_cells_aa<Cell>::sort_cells() + { + if(m_sorted) return; //Perform sort only the first time. + + add_curr_cell(); + m_curr_cell.x = std::numeric_limits<int>::max(); + m_curr_cell.y = std::numeric_limits<int>::max(); + m_curr_cell.cover = 0; + m_curr_cell.area = 0; + + if(m_num_cells == 0) return; + +// DBG: Check to see if min/max works well. +//for(unsigned nc = 0; nc < m_num_cells; nc++) +//{ +// cell_type* cell = m_cells[nc >> cell_block_shift] + (nc & cell_block_mask); +// if(cell->x < m_min_x || +// cell->y < m_min_y || +// cell->x > m_max_x || +// cell->y > m_max_y) +// { +// cell = cell; // Breakpoint here +// } +//} + // Allocate the array of cell pointers + m_sorted_cells.allocate(m_num_cells, 16); + + // Allocate and zero the Y array + m_sorted_y.allocate(m_max_y - m_min_y + 1, 16); + m_sorted_y.zero(); + + // Create the Y-histogram (count the numbers of cells for each Y) + cell_type** block_ptr = m_cells; + cell_type* cell_ptr; + unsigned nb = m_num_cells; + unsigned i; + while(nb) + { + cell_ptr = *block_ptr++; + i = (nb > cell_block_size) ? unsigned(cell_block_size) : nb; + nb -= i; + while(i--) + { + m_sorted_y[cell_ptr->y - m_min_y].start++; + ++cell_ptr; + } + } + + // Convert the Y-histogram into the array of starting indexes + unsigned start = 0; + for(i = 0; i < m_sorted_y.size(); i++) + { + unsigned v = m_sorted_y[i].start; + m_sorted_y[i].start = start; + start += v; + } + + // Fill the cell pointer array sorted by Y + block_ptr = m_cells; + nb = m_num_cells; + while(nb) + { + cell_ptr = *block_ptr++; + i = (nb > cell_block_size) ? unsigned(cell_block_size) : nb; + nb -= i; + while(i--) + { + sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y]; + m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr; + ++curr_y.num; + ++cell_ptr; + } + } + + // Finally arrange the X-arrays + for(i = 0; i < m_sorted_y.size(); i++) + { + const sorted_y& curr_y = m_sorted_y[i]; + if(curr_y.num) + { + qsort_cells(m_sorted_cells.data() + curr_y.start, curr_y.num); + } + } + m_sorted = true; + } + + + + //------------------------------------------------------scanline_hit_test + class scanline_hit_test + { + public: + scanline_hit_test(int x) : m_x(x), m_hit(false) {} + + void reset_spans() {} + void finalize(int) {} + void add_cell(int x, int) + { + if(m_x == x) m_hit = true; + } + void add_span(int x, int len, int) + { + if(m_x >= x && m_x < x+len) m_hit = true; + } + unsigned num_spans() const { return 1; } + bool hit() const { return m_hit; } + + private: + int m_x; + bool m_hit; + }; + + +} + +#endif diff --git a/include/agg_rasterizer_compound_aa.h b/include/agg_rasterizer_compound_aa.h new file mode 100644 index 0000000..72d811b --- /dev/null +++ b/include/agg_rasterizer_compound_aa.h @@ -0,0 +1,665 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.3 +// Copyright (C) 2002-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. +// +//---------------------------------------------------------------------------- +// +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// libray - in producing this work. See http://www.freetype.org for details. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_COMPOUND_AA_INCLUDED +#define AGG_RASTERIZER_COMPOUND_AA_INCLUDED + +#include <limits> +#include "agg_rasterizer_cells_aa.h" +#include "agg_rasterizer_sl_clip.h" + +namespace agg +{ + + //-----------------------------------------------------------cell_style_aa + // A pixel cell. There're no constructors defined and it was done + // intentionally in order to avoid extra overhead when allocating an + // array of cells. + struct cell_style_aa + { + int x; + int y; + int cover; + int area; + int16 left, right; + + void initial() + { + x = std::numeric_limits<int>::max(); + y = std::numeric_limits<int>::max(); + cover = 0; + area = 0; + left = -1; + right = -1; + } + + void style(const cell_style_aa& c) + { + left = c.left; + right = c.right; + } + + int not_equal(int ex, int ey, const cell_style_aa& c) const + { + return ((unsigned)ex - (unsigned)x) | ((unsigned)ey - (unsigned)y) | + ((unsigned)left - (unsigned)c.left) | ((unsigned)right - (unsigned)c.right); + } + }; + + + //===========================================================layer_order_e + enum layer_order_e + { + layer_unsorted, //------layer_unsorted + layer_direct, //------layer_direct + layer_inverse //------layer_inverse + }; + + + //==================================================rasterizer_compound_aa + template<class Clip=rasterizer_sl_clip_int> class rasterizer_compound_aa + { + struct style_info + { + unsigned start_cell; + unsigned num_cells; + int last_x; + }; + + struct cell_info + { + int x, area, cover; + }; + + public: + typedef Clip clip_type; + typedef typename Clip::conv_type conv_type; + typedef typename Clip::coord_type coord_type; + + enum aa_scale_e + { + aa_shift = 8, + aa_scale = 1 << aa_shift, + aa_mask = aa_scale - 1, + aa_scale2 = aa_scale * 2, + aa_mask2 = aa_scale2 - 1 + }; + + //-------------------------------------------------------------------- + rasterizer_compound_aa() : + m_outline(), + m_clipper(), + m_filling_rule(fill_non_zero), + m_layer_order(layer_direct), + m_styles(), // Active Styles + m_ast(), // Active Style Table (unique values) + m_asm(), // Active Style Mask + m_cells(), + m_cover_buf(), + m_min_style(std::numeric_limits<int>::max()), + m_max_style(std::numeric_limits<int>::min()), + m_start_x(0), + m_start_y(0), + m_scan_y(std::numeric_limits<int>::max()), + m_sl_start(0), + m_sl_len(0) + {} + + //-------------------------------------------------------------------- + void reset(); + void reset_clipping(); + void clip_box(double x1, double y1, double x2, double y2); + void filling_rule(filling_rule_e filling_rule); + void layer_order(layer_order_e order); + + //-------------------------------------------------------------------- + void styles(int left, int right); + void move_to(int x, int y); + void line_to(int x, int y); + void move_to_d(double x, double y); + void line_to_d(double x, double y); + void add_vertex(double x, double y, unsigned cmd); + + void edge(int x1, int y1, int x2, int y2); + void edge_d(double x1, double y1, double x2, double y2); + + //------------------------------------------------------------------- + template<class VertexSource> + void add_path(VertexSource& vs, unsigned path_id=0) + { + double x; + double y; + + unsigned cmd; + vs.rewind(path_id); + if(m_outline.sorted()) reset(); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + add_vertex(x, y, cmd); + } + } + + + //-------------------------------------------------------------------- + int min_x() const { return m_outline.min_x(); } + int min_y() const { return m_outline.min_y(); } + int max_x() const { return m_outline.max_x(); } + int max_y() const { return m_outline.max_y(); } + int min_style() const { return m_min_style; } + int max_style() const { return m_max_style; } + + //-------------------------------------------------------------------- + void sort(); + bool rewind_scanlines(); + unsigned sweep_styles(); + int scanline_start() const { return m_sl_start; } + unsigned scanline_length() const { return m_sl_len; } + unsigned style(unsigned style_idx) const; + + cover_type* allocate_cover_buffer(unsigned len); + + //-------------------------------------------------------------------- + bool navigate_scanline(int y); + bool hit_test(int tx, int ty); + + //-------------------------------------------------------------------- + AGG_INLINE unsigned calculate_alpha(int area) const + { + int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift); + if(cover < 0) cover = -cover; + if(m_filling_rule == fill_even_odd) + { + cover &= aa_mask2; + if(cover > aa_scale) + { + cover = aa_scale2 - cover; + } + } + if(cover > aa_mask) cover = aa_mask; + return cover; + } + + //-------------------------------------------------------------------- + // Sweeps one scanline with one style index. The style ID can be + // determined by calling style(). + template<class Scanline> bool sweep_scanline(Scanline& sl, int style_idx) + { + int scan_y = m_scan_y - 1; + if(scan_y > m_outline.max_y()) return false; + + sl.reset_spans(); + + if(style_idx < 0) + { + style_idx = 0; + } + else + { + style_idx++; + } + + const style_info& st = m_styles[m_ast[style_idx]]; + + unsigned num_cells = st.num_cells; + cell_info* cell = &m_cells[st.start_cell]; + + int cover = 0; + while(num_cells--) + { + unsigned alpha; + int x = cell->x; + int area = cell->area; + + cover += cell->cover; + + ++cell; + + if(area) + { + alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area); + sl.add_cell(x, alpha); + x++; + } + + if(num_cells && cell->x > x) + { + alpha = calculate_alpha(cover << (poly_subpixel_shift + 1)); + if(alpha) + { + sl.add_span(x, cell->x - x, alpha); + } + } + } + + if(sl.num_spans() == 0) return false; + sl.finalize(scan_y); + return true; + } + + private: + void add_style(int style_id); + + //-------------------------------------------------------------------- + // Disable copying + rasterizer_compound_aa(const rasterizer_compound_aa<Clip>&); + const rasterizer_compound_aa<Clip>& + operator = (const rasterizer_compound_aa<Clip>&); + + private: + rasterizer_cells_aa<cell_style_aa> m_outline; + clip_type m_clipper; + filling_rule_e m_filling_rule; + layer_order_e m_layer_order; + pod_vector<style_info> m_styles; // Active Styles + pod_vector<unsigned> m_ast; // Active Style Table (unique values) + pod_vector<int8u> m_asm; // Active Style Mask + pod_vector<cell_info> m_cells; + pod_vector<cover_type> m_cover_buf; + + int m_min_style; + int m_max_style; + coord_type m_start_x; + coord_type m_start_y; + int m_scan_y; + int m_sl_start; + unsigned m_sl_len; + }; + + + + + + + + + + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::reset() + { + m_outline.reset(); + m_min_style = std::numeric_limits<int>::max(); + m_max_style = std::numeric_limits<int>::min(); + m_scan_y = std::numeric_limits<int>::max(); + m_sl_start = 0; + m_sl_len = 0; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::filling_rule(filling_rule_e filling_rule) + { + m_filling_rule = filling_rule; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::layer_order(layer_order_e order) + { + m_layer_order = order; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::clip_box(double x1, double y1, + double x2, double y2) + { + reset(); + m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1), + conv_type::upscale(x2), conv_type::upscale(y2)); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::reset_clipping() + { + reset(); + m_clipper.reset_clipping(); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::styles(int left, int right) + { + cell_style_aa cell; + cell.initial(); + cell.left = (int16)left; + cell.right = (int16)right; + m_outline.style(cell); + if(left >= 0 && left < m_min_style) m_min_style = left; + if(left >= 0 && left > m_max_style) m_max_style = left; + if(right >= 0 && right < m_min_style) m_min_style = right; + if(right >= 0 && right > m_max_style) m_max_style = right; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::move_to(int x, int y) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(m_start_x = conv_type::downscale(x), + m_start_y = conv_type::downscale(y)); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::line_to(int x, int y) + { + m_clipper.line_to(m_outline, + conv_type::downscale(x), + conv_type::downscale(y)); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::move_to_d(double x, double y) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(m_start_x = conv_type::upscale(x), + m_start_y = conv_type::upscale(y)); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::line_to_d(double x, double y) + { + m_clipper.line_to(m_outline, + conv_type::upscale(x), + conv_type::upscale(y)); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::add_vertex(double x, double y, unsigned cmd) + { + if(is_move_to(cmd)) + { + move_to_d(x, y); + } + else + if(is_vertex(cmd)) + { + line_to_d(x, y); + } + else + if(is_close(cmd)) + { + m_clipper.line_to(m_outline, m_start_x, m_start_y); + } + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::edge(int x1, int y1, int x2, int y2) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1)); + m_clipper.line_to(m_outline, + conv_type::downscale(x2), + conv_type::downscale(y2)); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_compound_aa<Clip>::edge_d(double x1, double y1, + double x2, double y2) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1)); + m_clipper.line_to(m_outline, + conv_type::upscale(x2), + conv_type::upscale(y2)); + } + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE void rasterizer_compound_aa<Clip>::sort() + { + m_outline.sort_cells(); + } + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE bool rasterizer_compound_aa<Clip>::rewind_scanlines() + { + m_outline.sort_cells(); + if(m_outline.total_cells() == 0) + { + return false; + } + if(m_max_style < m_min_style) + { + return false; + } + m_scan_y = m_outline.min_y(); + m_styles.allocate(m_max_style - m_min_style + 2, 128); + return true; + } + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE void rasterizer_compound_aa<Clip>::add_style(int style_id) + { + if(style_id < 0) style_id = 0; + else style_id -= m_min_style - 1; + + unsigned nbyte = style_id >> 3; + unsigned mask = 1 << (style_id & 7); + + style_info* style = &m_styles[style_id]; + if((m_asm[nbyte] & mask) == 0) + { + m_ast.add(style_id); + m_asm[nbyte] |= mask; + style->start_cell = 0; + style->num_cells = 0; + style->last_x = std::numeric_limits<int>::min(); + } + ++style->start_cell; + } + + //------------------------------------------------------------------------ + // Returns the number of styles + template<class Clip> + unsigned rasterizer_compound_aa<Clip>::sweep_styles() + { + for(;;) + { + if(m_scan_y > m_outline.max_y()) return 0; + unsigned num_cells = m_outline.scanline_num_cells(m_scan_y); + const cell_style_aa* const* cells = m_outline.scanline_cells(m_scan_y); + unsigned num_styles = m_max_style - m_min_style + 2; + const cell_style_aa* curr_cell; + unsigned style_id; + style_info* style; + cell_info* cell; + + m_cells.allocate(num_cells * 2, 256); // Each cell can have two styles + m_ast.capacity(num_styles, 64); + m_asm.allocate((num_styles + 7) >> 3, 8); + m_asm.zero(); + + if(num_cells) + { + // Pre-add zero (for no-fill style, that is, -1). + // We need that to ensure that the "-1 style" would go first. + m_asm[0] |= 1; + m_ast.add(0); + style = &m_styles[0]; + style->start_cell = 0; + style->num_cells = 0; + style->last_x = std::numeric_limits<int>::min(); + + m_sl_start = cells[0]->x; + m_sl_len = cells[num_cells-1]->x - m_sl_start + 1; + while(num_cells--) + { + curr_cell = *cells++; + add_style(curr_cell->left); + add_style(curr_cell->right); + } + + // Convert the Y-histogram into the array of starting indexes + unsigned i; + unsigned start_cell = 0; + for(i = 0; i < m_ast.size(); i++) + { + style_info& st = m_styles[m_ast[i]]; + unsigned v = st.start_cell; + st.start_cell = start_cell; + start_cell += v; + } + + cells = m_outline.scanline_cells(m_scan_y); + num_cells = m_outline.scanline_num_cells(m_scan_y); + + while(num_cells--) + { + curr_cell = *cells++; + style_id = (curr_cell->left < 0) ? 0 : + curr_cell->left - m_min_style + 1; + + style = &m_styles[style_id]; + if(curr_cell->x == style->last_x) + { + cell = &m_cells[style->start_cell + style->num_cells - 1]; + cell->area += curr_cell->area; + cell->cover += curr_cell->cover; + } + else + { + cell = &m_cells[style->start_cell + style->num_cells]; + cell->x = curr_cell->x; + cell->area = curr_cell->area; + cell->cover = curr_cell->cover; + style->last_x = curr_cell->x; + style->num_cells++; + } + + style_id = (curr_cell->right < 0) ? 0 : + curr_cell->right - m_min_style + 1; + + style = &m_styles[style_id]; + if(curr_cell->x == style->last_x) + { + cell = &m_cells[style->start_cell + style->num_cells - 1]; + cell->area -= curr_cell->area; + cell->cover -= curr_cell->cover; + } + else + { + cell = &m_cells[style->start_cell + style->num_cells]; + cell->x = curr_cell->x; + cell->area = -curr_cell->area; + cell->cover = -curr_cell->cover; + style->last_x = curr_cell->x; + style->num_cells++; + } + } + } + if(m_ast.size() > 1) break; + ++m_scan_y; + } + ++m_scan_y; + + if(m_layer_order != layer_unsorted) + { + range_adaptor<pod_vector<unsigned> > ra(m_ast, 1, m_ast.size() - 1); + if(m_layer_order == layer_direct) quick_sort(ra, unsigned_greater); + else quick_sort(ra, unsigned_less); + } + + return m_ast.size() - 1; + } + + //------------------------------------------------------------------------ + // Returns style ID depending of the existing style index + template<class Clip> + AGG_INLINE + unsigned rasterizer_compound_aa<Clip>::style(unsigned style_idx) const + { + return m_ast[style_idx + 1] + m_min_style - 1; + } + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE bool rasterizer_compound_aa<Clip>::navigate_scanline(int y) + { + m_outline.sort_cells(); + if(m_outline.total_cells() == 0) + { + return false; + } + if(m_max_style < m_min_style) + { + return false; + } + if(y < m_outline.min_y() || y > m_outline.max_y()) + { + return false; + } + m_scan_y = y; + m_styles.allocate(m_max_style - m_min_style + 2, 128); + return true; + } + + //------------------------------------------------------------------------ + template<class Clip> + bool rasterizer_compound_aa<Clip>::hit_test(int tx, int ty) + { + if(!navigate_scanline(ty)) + { + return false; + } + + unsigned num_styles = sweep_styles(); + if(num_styles <= 0) + { + return false; + } + + scanline_hit_test sl(tx); + sweep_scanline(sl, -1); + return sl.hit(); + } + + //------------------------------------------------------------------------ + template<class Clip> + cover_type* rasterizer_compound_aa<Clip>::allocate_cover_buffer(unsigned len) + { + m_cover_buf.allocate(len, 256); + return &m_cover_buf[0]; + } + +} + + + +#endif + diff --git a/include/agg_rasterizer_outline.h b/include/agg_rasterizer_outline.h new file mode 100644 index 0000000..65203e3 --- /dev/null +++ b/include/agg_rasterizer_outline.h @@ -0,0 +1,147 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_OUTLINE_INCLUDED +#define AGG_RASTERIZER_OUTLINE_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //======================================================rasterizer_outline + template<class Renderer> class rasterizer_outline + { + public: + explicit rasterizer_outline(Renderer& ren) : + m_ren(&ren), + m_start_x(0), + m_start_y(0), + m_vertices(0) + {} + void attach(Renderer& ren) { m_ren = &ren; } + + + //-------------------------------------------------------------------- + void move_to(int x, int y) + { + m_vertices = 1; + m_ren->move_to(m_start_x = x, m_start_y = y); + } + + //-------------------------------------------------------------------- + void line_to(int x, int y) + { + ++m_vertices; + m_ren->line_to(x, y); + } + + //-------------------------------------------------------------------- + void move_to_d(double x, double y) + { + move_to(m_ren->coord(x), m_ren->coord(y)); + } + + //-------------------------------------------------------------------- + void line_to_d(double x, double y) + { + line_to(m_ren->coord(x), m_ren->coord(y)); + } + + //-------------------------------------------------------------------- + void close() + { + if(m_vertices > 2) + { + line_to(m_start_x, m_start_y); + } + m_vertices = 0; + } + + //-------------------------------------------------------------------- + void add_vertex(double x, double y, unsigned cmd) + { + if(is_move_to(cmd)) + { + move_to_d(x, y); + } + else + { + if(is_end_poly(cmd)) + { + if(is_closed(cmd)) close(); + } + else + { + line_to_d(x, y); + } + } + } + + + //-------------------------------------------------------------------- + template<class VertexSource> + void add_path(VertexSource& vs, unsigned path_id=0) + { + double x; + double y; + + unsigned cmd; + vs.rewind(path_id); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + add_vertex(x, y, cmd); + } + } + + + //-------------------------------------------------------------------- + template<class VertexSource, class ColorStorage, class PathId> + void render_all_paths(VertexSource& vs, + const ColorStorage& colors, + const PathId& path_id, + unsigned num_paths) + { + for(unsigned i = 0; i < num_paths; i++) + { + m_ren->line_color(colors[i]); + add_path(vs, path_id[i]); + } + } + + + //-------------------------------------------------------------------- + template<class Ctrl> void render_ctrl(Ctrl& c) + { + unsigned i; + for(i = 0; i < c.num_paths(); i++) + { + m_ren->line_color(c.color(i)); + add_path(c, i); + } + } + + + private: + Renderer* m_ren; + int m_start_x; + int m_start_y; + unsigned m_vertices; + }; + + +} + + +#endif + diff --git a/include/agg_rasterizer_outline_aa.h b/include/agg_rasterizer_outline_aa.h new file mode 100644 index 0000000..1f60331 --- /dev/null +++ b/include/agg_rasterizer_outline_aa.h @@ -0,0 +1,600 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_OUTLINE_AA_INCLUDED +#define AGG_RASTERIZER_OUTLINE_AA_INCLUDED + +#include <cmath> +#include "agg_basics.h" +#include "agg_line_aa_basics.h" +#include "agg_vertex_sequence.h" + +namespace agg +{ + + //------------------------------------------------------------------------- + inline bool cmp_dist_start(int d) { return d > 0; } + inline bool cmp_dist_end(int d) { return d <= 0; } + + + + //-----------------------------------------------------------line_aa_vertex + // Vertex (x, y) with the distance to the next one. The last vertex has + // the distance between the last and the first points + struct line_aa_vertex + { + int x; + int y; + int len; + + line_aa_vertex() {} + line_aa_vertex(int x_, int y_) : + x(x_), + y(y_), + len(0) + { + } + + bool operator () (const line_aa_vertex& val) + { + double dx = val.x - x; + double dy = val.y - y; + return (len = uround(std::sqrt(dx * dx + dy * dy))) > + (line_subpixel_scale + line_subpixel_scale / 2); + } + }; + + + //----------------------------------------------------------outline_aa_join_e + enum outline_aa_join_e + { + outline_no_join, //-----outline_no_join + outline_miter_join, //-----outline_miter_join + outline_round_join, //-----outline_round_join + outline_miter_accurate_join //-----outline_accurate_join + }; + + //=======================================================rasterizer_outline_aa + template<class Renderer, class Coord=line_coord> class rasterizer_outline_aa + { + private: + //------------------------------------------------------------------------ + struct draw_vars + { + unsigned idx; + int x1, y1, x2, y2; + line_parameters curr, next; + int lcurr, lnext; + int xb1, yb1, xb2, yb2; + unsigned flags; + }; + + void draw(draw_vars& dv, unsigned start, unsigned end); + + public: + typedef line_aa_vertex vertex_type; + typedef vertex_sequence<vertex_type, 6> vertex_storage_type; + + explicit rasterizer_outline_aa(Renderer& ren) : + m_ren(&ren), + m_line_join(ren.accurate_join_only() ? + outline_miter_accurate_join : + outline_round_join), + m_round_cap(false), + m_start_x(0), + m_start_y(0) + {} + void attach(Renderer& ren) { m_ren = &ren; } + + //------------------------------------------------------------------------ + void line_join(outline_aa_join_e join) + { + m_line_join = m_ren->accurate_join_only() ? + outline_miter_accurate_join : + join; + } + bool line_join() const { return m_line_join; } + + //------------------------------------------------------------------------ + void round_cap(bool v) { m_round_cap = v; } + bool round_cap() const { return m_round_cap; } + + //------------------------------------------------------------------------ + void move_to(int x, int y) + { + m_src_vertices.modify_last(vertex_type(m_start_x = x, m_start_y = y)); + } + + //------------------------------------------------------------------------ + void line_to(int x, int y) + { + m_src_vertices.add(vertex_type(x, y)); + } + + //------------------------------------------------------------------------ + void move_to_d(double x, double y) + { + move_to(Coord::conv(x), Coord::conv(y)); + } + + //------------------------------------------------------------------------ + void line_to_d(double x, double y) + { + line_to(Coord::conv(x), Coord::conv(y)); + } + + //------------------------------------------------------------------------ + void render(bool close_polygon); + + //------------------------------------------------------------------------ + void add_vertex(double x, double y, unsigned cmd) + { + if(is_move_to(cmd)) + { + render(false); + move_to_d(x, y); + } + else + { + if(is_end_poly(cmd)) + { + render(is_closed(cmd)); + if(is_closed(cmd)) + { + move_to(m_start_x, m_start_y); + } + } + else + { + line_to_d(x, y); + } + } + } + + //------------------------------------------------------------------------ + template<class VertexSource> + void add_path(VertexSource& vs, unsigned path_id=0) + { + double x; + double y; + + unsigned cmd; + vs.rewind(path_id); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + add_vertex(x, y, cmd); + } + render(false); + } + + + //------------------------------------------------------------------------ + template<class VertexSource, class ColorStorage, class PathId> + void render_all_paths(VertexSource& vs, + const ColorStorage& colors, + const PathId& path_id, + unsigned num_paths) + { + for(unsigned i = 0; i < num_paths; i++) + { + m_ren->color(colors[i]); + add_path(vs, path_id[i]); + } + } + + + //------------------------------------------------------------------------ + template<class Ctrl> void render_ctrl(Ctrl& c) + { + unsigned i; + for(i = 0; i < c.num_paths(); i++) + { + m_ren->color(c.color(i)); + add_path(c, i); + } + } + + private: + rasterizer_outline_aa(const rasterizer_outline_aa<Renderer, Coord>&); + const rasterizer_outline_aa<Renderer, Coord>& operator = + (const rasterizer_outline_aa<Renderer, Coord>&); + + Renderer* m_ren; + vertex_storage_type m_src_vertices; + outline_aa_join_e m_line_join; + bool m_round_cap; + int m_start_x; + int m_start_y; + }; + + + + + + + + + //---------------------------------------------------------------------------- + template<class Renderer, class Coord> + void rasterizer_outline_aa<Renderer, Coord>::draw(draw_vars& dv, + unsigned start, + unsigned end) + { + unsigned i; + const vertex_storage_type::value_type* v; + + for(i = start; i < end; i++) + { + if(m_line_join == outline_round_join) + { + dv.xb1 = dv.curr.x1 + (dv.curr.y2 - dv.curr.y1); + dv.yb1 = dv.curr.y1 - (dv.curr.x2 - dv.curr.x1); + dv.xb2 = dv.curr.x2 + (dv.curr.y2 - dv.curr.y1); + dv.yb2 = dv.curr.y2 - (dv.curr.x2 - dv.curr.x1); + } + + switch(dv.flags) + { + case 0: m_ren->line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break; + case 1: m_ren->line2(dv.curr, dv.xb2, dv.yb2); break; + case 2: m_ren->line1(dv.curr, dv.xb1, dv.yb1); break; + case 3: m_ren->line0(dv.curr); break; + } + + if(m_line_join == outline_round_join && (dv.flags & 2) == 0) + { + m_ren->pie(dv.curr.x2, dv.curr.y2, + dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), + dv.curr.y2 - (dv.curr.x2 - dv.curr.x1), + dv.curr.x2 + (dv.next.y2 - dv.next.y1), + dv.curr.y2 - (dv.next.x2 - dv.next.x1)); + } + + dv.x1 = dv.x2; + dv.y1 = dv.y2; + dv.lcurr = dv.lnext; + dv.lnext = m_src_vertices[dv.idx].len; + + ++dv.idx; + if(dv.idx >= m_src_vertices.size()) dv.idx = 0; + + v = &m_src_vertices[dv.idx]; + dv.x2 = v->x; + dv.y2 = v->y; + + dv.curr = dv.next; + dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext); + dv.xb1 = dv.xb2; + dv.yb1 = dv.yb2; + + switch(m_line_join) + { + case outline_no_join: + dv.flags = 3; + break; + + case outline_miter_join: + dv.flags >>= 1; + dv.flags |= ((dv.curr.diagonal_quadrant() == + dv.next.diagonal_quadrant()) << 1); + if((dv.flags & 2) == 0) + { + bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2); + } + break; + + case outline_round_join: + dv.flags >>= 1; + dv.flags |= ((dv.curr.diagonal_quadrant() == + dv.next.diagonal_quadrant()) << 1); + break; + + case outline_miter_accurate_join: + dv.flags = 0; + bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2); + break; + } + } + } + + + + + //---------------------------------------------------------------------------- + template<class Renderer, class Coord> + void rasterizer_outline_aa<Renderer, Coord>::render(bool close_polygon) + { + m_src_vertices.close(close_polygon); + draw_vars dv; + const vertex_storage_type::value_type* v; + int x1; + int y1; + int x2; + int y2; + int lprev; + + if(close_polygon) + { + if(m_src_vertices.size() >= 3) + { + dv.idx = 2; + + v = &m_src_vertices[m_src_vertices.size() - 1]; + x1 = v->x; + y1 = v->y; + lprev = v->len; + + v = &m_src_vertices[0]; + x2 = v->x; + y2 = v->y; + dv.lcurr = v->len; + line_parameters prev(x1, y1, x2, y2, lprev); + + v = &m_src_vertices[1]; + dv.x1 = v->x; + dv.y1 = v->y; + dv.lnext = v->len; + dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr); + + v = &m_src_vertices[dv.idx]; + dv.x2 = v->x; + dv.y2 = v->y; + dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext); + + dv.xb1 = 0; + dv.yb1 = 0; + dv.xb2 = 0; + dv.yb2 = 0; + + switch(m_line_join) + { + case outline_no_join: + dv.flags = 3; + break; + + case outline_miter_join: + case outline_round_join: + dv.flags = + (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) | + ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1); + break; + + case outline_miter_accurate_join: + dv.flags = 0; + break; + } + + if((dv.flags & 1) == 0 && m_line_join != outline_round_join) + { + bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1); + } + + if((dv.flags & 2) == 0 && m_line_join != outline_round_join) + { + bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2); + } + draw(dv, 0, m_src_vertices.size()); + } + } + else + { + switch(m_src_vertices.size()) + { + case 0: + case 1: + break; + + case 2: + { + v = &m_src_vertices[0]; + x1 = v->x; + y1 = v->y; + lprev = v->len; + v = &m_src_vertices[1]; + x2 = v->x; + y2 = v->y; + line_parameters lp(x1, y1, x2, y2, lprev); + if(m_round_cap) + { + m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); + } + m_ren->line3(lp, + x1 + (y2 - y1), + y1 - (x2 - x1), + x2 + (y2 - y1), + y2 - (x2 - x1)); + if(m_round_cap) + { + m_ren->semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1)); + } + } + break; + + case 3: + { + int x3, y3; + int lnext; + v = &m_src_vertices[0]; + x1 = v->x; + y1 = v->y; + lprev = v->len; + v = &m_src_vertices[1]; + x2 = v->x; + y2 = v->y; + lnext = v->len; + v = &m_src_vertices[2]; + x3 = v->x; + y3 = v->y; + line_parameters lp1(x1, y1, x2, y2, lprev); + line_parameters lp2(x2, y2, x3, y3, lnext); + + if(m_round_cap) + { + m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); + } + + if(m_line_join == outline_round_join) + { + m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), + x2 + (y2 - y1), y2 - (x2 - x1)); + + m_ren->pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1), + x2 + (y3 - y2), y2 - (x3 - x2)); + + m_ren->line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2), + x3 + (y3 - y2), y3 - (x3 - x2)); + } + else + { + bisectrix(lp1, lp2, &dv.xb1, &dv.yb1); + m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1), + dv.xb1, dv.yb1); + + m_ren->line3(lp2, dv.xb1, dv.yb1, + x3 + (y3 - y2), y3 - (x3 - x2)); + } + if(m_round_cap) + { + m_ren->semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2)); + } + } + break; + + default: + { + dv.idx = 3; + + v = &m_src_vertices[0]; + x1 = v->x; + y1 = v->y; + lprev = v->len; + + v = &m_src_vertices[1]; + x2 = v->x; + y2 = v->y; + dv.lcurr = v->len; + line_parameters prev(x1, y1, x2, y2, lprev); + + v = &m_src_vertices[2]; + dv.x1 = v->x; + dv.y1 = v->y; + dv.lnext = v->len; + dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr); + + v = &m_src_vertices[dv.idx]; + dv.x2 = v->x; + dv.y2 = v->y; + dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext); + + dv.xb1 = 0; + dv.yb1 = 0; + dv.xb2 = 0; + dv.yb2 = 0; + + switch(m_line_join) + { + case outline_no_join: + dv.flags = 3; + break; + + case outline_miter_join: + case outline_round_join: + dv.flags = + (prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) | + ((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1); + break; + + case outline_miter_accurate_join: + dv.flags = 0; + break; + } + + if(m_round_cap) + { + m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1)); + } + if((dv.flags & 1) == 0) + { + if(m_line_join == outline_round_join) + { + m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), + x2 + (y2 - y1), y2 - (x2 - x1)); + m_ren->pie(prev.x2, prev.y2, + x2 + (y2 - y1), y2 - (x2 - x1), + dv.curr.x1 + (dv.curr.y2 - dv.curr.y1), + dv.curr.y1 - (dv.curr.x2 - dv.curr.x1)); + } + else + { + bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1); + m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1), + dv.xb1, dv.yb1); + } + } + else + { + m_ren->line1(prev, + x1 + (y2 - y1), + y1 - (x2 - x1)); + } + if((dv.flags & 2) == 0 && m_line_join != outline_round_join) + { + bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2); + } + + draw(dv, 1, m_src_vertices.size() - 2); + + if((dv.flags & 1) == 0) + { + if(m_line_join == outline_round_join) + { + m_ren->line3(dv.curr, + dv.curr.x1 + (dv.curr.y2 - dv.curr.y1), + dv.curr.y1 - (dv.curr.x2 - dv.curr.x1), + dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), + dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); + } + else + { + m_ren->line3(dv.curr, dv.xb1, dv.yb1, + dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), + dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); + } + } + else + { + m_ren->line2(dv.curr, + dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), + dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); + } + if(m_round_cap) + { + m_ren->semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2, + dv.curr.x2 + (dv.curr.y2 - dv.curr.y1), + dv.curr.y2 - (dv.curr.x2 - dv.curr.x1)); + } + + } + break; + } + } + m_src_vertices.remove_all(); + } + + +} + + +#endif + diff --git a/include/agg_rasterizer_scanline_aa.h b/include/agg_rasterizer_scanline_aa.h new file mode 100644 index 0000000..b788afe --- /dev/null +++ b/include/agg_rasterizer_scanline_aa.h @@ -0,0 +1,481 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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. +// +//---------------------------------------------------------------------------- +// +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// libray - in producing this work. See http://www.freetype.org for details. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED +#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED + +#include "agg_rasterizer_cells_aa.h" +#include "agg_rasterizer_sl_clip.h" +#include "agg_rasterizer_scanline_aa_nogamma.h" +#include "agg_gamma_functions.h" + + +namespace agg +{ + //==================================================rasterizer_scanline_aa + // Polygon rasterizer that is used to render filled polygons with + // high-quality Anti-Aliasing. Internally, by default, the class uses + // integer coordinates in format 24.8, i.e. 24 bits for integer part + // and 8 bits for fractional - see poly_subpixel_shift. This class can be + // used in the following way: + // + // 1. filling_rule(filling_rule_e ft) - optional. + // + // 2. gamma() - optional. + // + // 3. reset() + // + // 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create + // more than one contour, but each contour must consist of at least 3 + // vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3); + // is the absolute minimum of vertices that define a triangle. + // The algorithm does not check either the number of vertices nor + // coincidence of their coordinates, but in the worst case it just + // won't draw anything. + // The orger of the vertices (clockwise or counterclockwise) + // is important when using the non-zero filling rule (fill_non_zero). + // In this case the vertex order of all the contours must be the same + // if you want your intersecting polygons to be without "holes". + // You actually can use different vertices order. If the contours do not + // intersect each other the order is not important anyway. If they do, + // contours with the same vertex order will be rendered without "holes" + // while the intersecting contours with different orders will have "holes". + // + // filling_rule() and gamma() can be called anytime before "sweeping". + //------------------------------------------------------------------------ + template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa + { + enum status + { + status_initial, + status_move_to, + status_line_to, + status_closed + }; + + public: + typedef Clip clip_type; + typedef typename Clip::conv_type conv_type; + typedef typename Clip::coord_type coord_type; + + enum aa_scale_e + { + aa_shift = 8, + aa_scale = 1 << aa_shift, + aa_mask = aa_scale - 1, + aa_scale2 = aa_scale * 2, + aa_mask2 = aa_scale2 - 1 + }; + + //-------------------------------------------------------------------- + rasterizer_scanline_aa(unsigned cell_block_limit=1024) : + m_outline(cell_block_limit), + m_clipper(), + m_filling_rule(fill_non_zero), + m_auto_close(true), + m_start_x(0), + m_start_y(0), + m_status(status_initial) + { + int i; + for(i = 0; i < aa_scale; i++) m_gamma[i] = i; + } + + //-------------------------------------------------------------------- + template<class GammaF> + rasterizer_scanline_aa(const GammaF& gamma_function, unsigned cell_block_limit) : + m_outline(cell_block_limit), + m_clipper(m_outline), + m_filling_rule(fill_non_zero), + m_auto_close(true), + m_start_x(0), + m_start_y(0), + m_status(status_initial) + { + gamma(gamma_function); + } + + //-------------------------------------------------------------------- + void reset(); + void reset_clipping(); + void clip_box(double x1, double y1, double x2, double y2); + void filling_rule(filling_rule_e filling_rule); + void auto_close(bool flag) { m_auto_close = flag; } + + //-------------------------------------------------------------------- + template<class GammaF> void gamma(const GammaF& gamma_function) + { + int i; + for(i = 0; i < aa_scale; i++) + { + m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask); + } + } + + //-------------------------------------------------------------------- + unsigned apply_gamma(unsigned cover) const + { + return m_gamma[cover]; + } + + //-------------------------------------------------------------------- + void move_to(int x, int y); + void line_to(int x, int y); + void move_to_d(double x, double y); + void line_to_d(double x, double y); + void close_polygon(); + void add_vertex(double x, double y, unsigned cmd); + + void edge(int x1, int y1, int x2, int y2); + void edge_d(double x1, double y1, double x2, double y2); + + //------------------------------------------------------------------- + template<class VertexSource> + void add_path(VertexSource& vs, unsigned path_id=0) + { + double x; + double y; + + unsigned cmd; + vs.rewind(path_id); + if(m_outline.sorted()) reset(); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + add_vertex(x, y, cmd); + } + } + + //-------------------------------------------------------------------- + int min_x() const { return m_outline.min_x(); } + int min_y() const { return m_outline.min_y(); } + int max_x() const { return m_outline.max_x(); } + int max_y() const { return m_outline.max_y(); } + + //-------------------------------------------------------------------- + void sort(); + bool rewind_scanlines(); + bool navigate_scanline(int y); + + //-------------------------------------------------------------------- + AGG_INLINE unsigned calculate_alpha(int area) const + { + int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift); + + if(cover < 0) cover = -cover; + if(m_filling_rule == fill_even_odd) + { + cover &= aa_mask2; + if(cover > aa_scale) + { + cover = aa_scale2 - cover; + } + } + if(cover > aa_mask) cover = aa_mask; + return m_gamma[cover]; + } + + //-------------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + for(;;) + { + if(m_scan_y > m_outline.max_y()) return false; + sl.reset_spans(); + unsigned num_cells = m_outline.scanline_num_cells(m_scan_y); + const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y); + int cover = 0; + + while(num_cells) + { + const cell_aa* cur_cell = *cells; + int x = cur_cell->x; + int area = cur_cell->area; + unsigned alpha; + + cover += cur_cell->cover; + + //accumulate all cells with the same X + while(--num_cells) + { + cur_cell = *++cells; + if(cur_cell->x != x) break; + area += cur_cell->area; + cover += cur_cell->cover; + } + + if(area) + { + alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area); + if(alpha) + { + sl.add_cell(x, alpha); + } + x++; + } + + if(num_cells && cur_cell->x > x) + { + alpha = calculate_alpha(cover << (poly_subpixel_shift + 1)); + if(alpha) + { + sl.add_span(x, cur_cell->x - x, alpha); + } + } + } + + if(sl.num_spans()) break; + ++m_scan_y; + } + + sl.finalize(m_scan_y); + ++m_scan_y; + return true; + } + + //-------------------------------------------------------------------- + bool hit_test(int tx, int ty); + + + private: + //-------------------------------------------------------------------- + // Disable copying + rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&); + const rasterizer_scanline_aa<Clip>& + operator = (const rasterizer_scanline_aa<Clip>&); + + private: + rasterizer_cells_aa<cell_aa> m_outline; + clip_type m_clipper; + int m_gamma[aa_scale]; + filling_rule_e m_filling_rule; + bool m_auto_close; + coord_type m_start_x; + coord_type m_start_y; + unsigned m_status; + int m_scan_y; + }; + + + + + + + + + + + + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::reset() + { + m_outline.reset(); + m_status = status_initial; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule) + { + m_filling_rule = filling_rule; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1, + double x2, double y2) + { + reset(); + m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1), + conv_type::upscale(x2), conv_type::upscale(y2)); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::reset_clipping() + { + reset(); + m_clipper.reset_clipping(); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::close_polygon() + { + if(m_status == status_line_to) + { + m_clipper.line_to(m_outline, m_start_x, m_start_y); + m_status = status_closed; + } + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::move_to(int x, int y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::downscale(x), + m_start_y = conv_type::downscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::line_to(int x, int y) + { + m_clipper.line_to(m_outline, + conv_type::downscale(x), + conv_type::downscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::upscale(x), + m_start_y = conv_type::upscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y) + { + m_clipper.line_to(m_outline, + conv_type::upscale(x), + conv_type::upscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::add_vertex(double x, double y, unsigned cmd) + { + if(is_move_to(cmd)) + { + move_to_d(x, y); + } + else + if(is_vertex(cmd)) + { + line_to_d(x, y); + } + else + if(is_close(cmd)) + { + close_polygon(); + } + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::edge(int x1, int y1, int x2, int y2) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1)); + m_clipper.line_to(m_outline, + conv_type::downscale(x2), + conv_type::downscale(y2)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1, + double x2, double y2) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1)); + m_clipper.line_to(m_outline, + conv_type::upscale(x2), + conv_type::upscale(y2)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::sort() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + } + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE bool rasterizer_scanline_aa<Clip>::rewind_scanlines() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0) + { + return false; + } + m_scan_y = m_outline.min_y(); + return true; + } + + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y) + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0 || + y < m_outline.min_y() || + y > m_outline.max_y()) + { + return false; + } + m_scan_y = y; + return true; + } + + //------------------------------------------------------------------------ + template<class Clip> + bool rasterizer_scanline_aa<Clip>::hit_test(int tx, int ty) + { + if(!navigate_scanline(ty)) return false; + scanline_hit_test sl(tx); + sweep_scanline(sl); + return sl.hit(); + } + + + +} + + + +#endif + diff --git a/include/agg_rasterizer_scanline_aa_nogamma.h b/include/agg_rasterizer_scanline_aa_nogamma.h new file mode 100644 index 0000000..4e93539 --- /dev/null +++ b/include/agg_rasterizer_scanline_aa_nogamma.h @@ -0,0 +1,483 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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. +// +//---------------------------------------------------------------------------- +// +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// libray - in producing this work. See http://www.freetype.org for details. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED +#define AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED + +#include <limits> +#include "agg_rasterizer_cells_aa.h" +#include "agg_rasterizer_sl_clip.h" + + +namespace agg +{ + + + //-----------------------------------------------------------------cell_aa + // A pixel cell. There're no constructors defined and it was done + // intentionally in order to avoid extra overhead when allocating an + // array of cells. + struct cell_aa + { + int x; + int y; + int cover; + int area; + + void initial() + { + x = std::numeric_limits<int>::max(); + y = std::numeric_limits<int>::max(); + cover = 0; + area = 0; + } + + void style(const cell_aa&) {} + + int not_equal(int ex, int ey, const cell_aa&) const + { + return ((unsigned)ex - (unsigned)x) | ((unsigned)ey - (unsigned)y); + } + }; + + + //==================================================rasterizer_scanline_aa_nogamma + // Polygon rasterizer that is used to render filled polygons with + // high-quality Anti-Aliasing. Internally, by default, the class uses + // integer coordinates in format 24.8, i.e. 24 bits for integer part + // and 8 bits for fractional - see poly_subpixel_shift. This class can be + // used in the following way: + // + // 1. filling_rule(filling_rule_e ft) - optional. + // + // 2. gamma() - optional. + // + // 3. reset() + // + // 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create + // more than one contour, but each contour must consist of at least 3 + // vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3); + // is the absolute minimum of vertices that define a triangle. + // The algorithm does not check either the number of vertices nor + // coincidence of their coordinates, but in the worst case it just + // won't draw anything. + // The orger of the vertices (clockwise or counterclockwise) + // is important when using the non-zero filling rule (fill_non_zero). + // In this case the vertex order of all the contours must be the same + // if you want your intersecting polygons to be without "holes". + // You actually can use different vertices order. If the contours do not + // intersect each other the order is not important anyway. If they do, + // contours with the same vertex order will be rendered without "holes" + // while the intersecting contours with different orders will have "holes". + // + // filling_rule() and gamma() can be called anytime before "sweeping". + //------------------------------------------------------------------------ + template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa_nogamma + { + enum status + { + status_initial, + status_move_to, + status_line_to, + status_closed + }; + + public: + typedef Clip clip_type; + typedef typename Clip::conv_type conv_type; + typedef typename Clip::coord_type coord_type; + + enum aa_scale_e + { + aa_shift = 8, + aa_scale = 1 << aa_shift, + aa_mask = aa_scale - 1, + aa_scale2 = aa_scale * 2, + aa_mask2 = aa_scale2 - 1 + }; + + //-------------------------------------------------------------------- + rasterizer_scanline_aa_nogamma(unsigned cell_block_limit=1024) : + m_outline(cell_block_limit), + m_clipper(), + m_filling_rule(fill_non_zero), + m_auto_close(true), + m_start_x(0), + m_start_y(0), + m_status(status_initial) + { + } + + //-------------------------------------------------------------------- + void reset(); + void reset_clipping(); + void clip_box(double x1, double y1, double x2, double y2); + void filling_rule(filling_rule_e filling_rule); + void auto_close(bool flag) { m_auto_close = flag; } + + //-------------------------------------------------------------------- + unsigned apply_gamma(unsigned cover) const + { + return cover; + } + + //-------------------------------------------------------------------- + void move_to(int x, int y); + void line_to(int x, int y); + void move_to_d(double x, double y); + void line_to_d(double x, double y); + void close_polygon(); + void add_vertex(double x, double y, unsigned cmd); + + void edge(int x1, int y1, int x2, int y2); + void edge_d(double x1, double y1, double x2, double y2); + + //------------------------------------------------------------------- + template<class VertexSource> + void add_path(VertexSource& vs, unsigned path_id=0) + { + double x; + double y; + + unsigned cmd; + vs.rewind(path_id); + if(m_outline.sorted()) reset(); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + add_vertex(x, y, cmd); + } + } + + //-------------------------------------------------------------------- + int min_x() const { return m_outline.min_x(); } + int min_y() const { return m_outline.min_y(); } + int max_x() const { return m_outline.max_x(); } + int max_y() const { return m_outline.max_y(); } + + //-------------------------------------------------------------------- + void sort(); + bool rewind_scanlines(); + bool navigate_scanline(int y); + + //-------------------------------------------------------------------- + AGG_INLINE unsigned calculate_alpha(int area) const + { + int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift); + + if(cover < 0) cover = -cover; + if(m_filling_rule == fill_even_odd) + { + cover &= aa_mask2; + if(cover > aa_scale) + { + cover = aa_scale2 - cover; + } + } + if(cover > aa_mask) cover = aa_mask; + return cover; + } + + //-------------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + for(;;) + { + if(m_scan_y > m_outline.max_y()) return false; + sl.reset_spans(); + unsigned num_cells = m_outline.scanline_num_cells(m_scan_y); + const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y); + int cover = 0; + + while(num_cells) + { + const cell_aa* cur_cell = *cells; + int x = cur_cell->x; + int area = cur_cell->area; + unsigned alpha; + + cover += cur_cell->cover; + + //accumulate all cells with the same X + while(--num_cells) + { + cur_cell = *++cells; + if(cur_cell->x != x) break; + area += cur_cell->area; + cover += cur_cell->cover; + } + + if(area) + { + alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area); + if(alpha) + { + sl.add_cell(x, alpha); + } + x++; + } + + if(num_cells && cur_cell->x > x) + { + alpha = calculate_alpha(cover << (poly_subpixel_shift + 1)); + if(alpha) + { + sl.add_span(x, cur_cell->x - x, alpha); + } + } + } + + if(sl.num_spans()) break; + ++m_scan_y; + } + + sl.finalize(m_scan_y); + ++m_scan_y; + return true; + } + + //-------------------------------------------------------------------- + bool hit_test(int tx, int ty); + + + private: + //-------------------------------------------------------------------- + // Disable copying + rasterizer_scanline_aa_nogamma(const rasterizer_scanline_aa_nogamma<Clip>&); + const rasterizer_scanline_aa_nogamma<Clip>& + operator = (const rasterizer_scanline_aa_nogamma<Clip>&); + + private: + rasterizer_cells_aa<cell_aa> m_outline; + clip_type m_clipper; + filling_rule_e m_filling_rule; + bool m_auto_close; + coord_type m_start_x; + coord_type m_start_y; + unsigned m_status; + int m_scan_y; + }; + + + + + + + + + + + + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::reset() + { + m_outline.reset(); + m_status = status_initial; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::filling_rule(filling_rule_e filling_rule) + { + m_filling_rule = filling_rule; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::clip_box(double x1, double y1, + double x2, double y2) + { + reset(); + m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1), + conv_type::upscale(x2), conv_type::upscale(y2)); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::reset_clipping() + { + reset(); + m_clipper.reset_clipping(); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::close_polygon() + { + if(m_status == status_line_to) + { + m_clipper.line_to(m_outline, m_start_x, m_start_y); + m_status = status_closed; + } + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::move_to(int x, int y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::downscale(x), + m_start_y = conv_type::downscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::line_to(int x, int y) + { + m_clipper.line_to(m_outline, + conv_type::downscale(x), + conv_type::downscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::move_to_d(double x, double y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::upscale(x), + m_start_y = conv_type::upscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::line_to_d(double x, double y) + { + m_clipper.line_to(m_outline, + conv_type::upscale(x), + conv_type::upscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::add_vertex(double x, double y, unsigned cmd) + { + if(is_move_to(cmd)) + { + move_to_d(x, y); + } + else + if(is_vertex(cmd)) + { + line_to_d(x, y); + } + else + if(is_close(cmd)) + { + close_polygon(); + } + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::edge(int x1, int y1, int x2, int y2) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1)); + m_clipper.line_to(m_outline, + conv_type::downscale(x2), + conv_type::downscale(y2)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::edge_d(double x1, double y1, + double x2, double y2) + { + if(m_outline.sorted()) reset(); + m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1)); + m_clipper.line_to(m_outline, + conv_type::upscale(x2), + conv_type::upscale(y2)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::sort() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + } + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::rewind_scanlines() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0) + { + return false; + } + m_scan_y = m_outline.min_y(); + return true; + } + + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::navigate_scanline(int y) + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0 || + y < m_outline.min_y() || + y > m_outline.max_y()) + { + return false; + } + m_scan_y = y; + return true; + } + + //------------------------------------------------------------------------ + template<class Clip> + bool rasterizer_scanline_aa_nogamma<Clip>::hit_test(int tx, int ty) + { + if(!navigate_scanline(ty)) return false; + scanline_hit_test sl(tx); + sweep_scanline(sl); + return sl.hit(); + } + + + +} + + + +#endif + diff --git a/include/agg_rasterizer_sl_clip.h b/include/agg_rasterizer_sl_clip.h new file mode 100644 index 0000000..3a7f3a1 --- /dev/null +++ b/include/agg_rasterizer_sl_clip.h @@ -0,0 +1,351 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_SL_CLIP_INCLUDED +#define AGG_RASTERIZER_SL_CLIP_INCLUDED + +#include "agg_clip_liang_barsky.h" + +namespace agg +{ + //--------------------------------------------------------poly_max_coord_e + enum poly_max_coord_e + { + poly_max_coord = (1 << 30) - 1 //----poly_max_coord + }; + + //------------------------------------------------------------ras_conv_int + struct ras_conv_int + { + typedef int coord_type; + static AGG_INLINE int mul_div(double a, double b, double c) + { + return iround(a * b / c); + } + static int xi(int v) { return v; } + static int yi(int v) { return v; } + static int upscale(double v) { return iround(v * poly_subpixel_scale); } + static int downscale(int v) { return v; } + }; + + //--------------------------------------------------------ras_conv_int_sat + struct ras_conv_int_sat + { + typedef int coord_type; + static AGG_INLINE int mul_div(double a, double b, double c) + { + return saturation<poly_max_coord>::iround(a * b / c); + } + static int xi(int v) { return v; } + static int yi(int v) { return v; } + static int upscale(double v) + { + return saturation<poly_max_coord>::iround(v * poly_subpixel_scale); + } + static int downscale(int v) { return v; } + }; + + //---------------------------------------------------------ras_conv_int_3x + struct ras_conv_int_3x + { + typedef int coord_type; + static AGG_INLINE int mul_div(double a, double b, double c) + { + return iround(a * b / c); + } + static int xi(int v) { return v * 3; } + static int yi(int v) { return v; } + static int upscale(double v) { return iround(v * poly_subpixel_scale); } + static int downscale(int v) { return v; } + }; + + //-----------------------------------------------------------ras_conv_dbl + struct ras_conv_dbl + { + typedef double coord_type; + static AGG_INLINE double mul_div(double a, double b, double c) + { + return a * b / c; + } + static int xi(double v) { return iround(v * poly_subpixel_scale); } + static int yi(double v) { return iround(v * poly_subpixel_scale); } + static double upscale(double v) { return v; } + static double downscale(int v) { return v / double(poly_subpixel_scale); } + }; + + //--------------------------------------------------------ras_conv_dbl_3x + struct ras_conv_dbl_3x + { + typedef double coord_type; + static AGG_INLINE double mul_div(double a, double b, double c) + { + return a * b / c; + } + static int xi(double v) { return iround(v * poly_subpixel_scale * 3); } + static int yi(double v) { return iround(v * poly_subpixel_scale); } + static double upscale(double v) { return v; } + static double downscale(int v) { return v / double(poly_subpixel_scale); } + }; + + + + + + //------------------------------------------------------rasterizer_sl_clip + template<class Conv> class rasterizer_sl_clip + { + public: + typedef Conv conv_type; + typedef typename Conv::coord_type coord_type; + typedef rect_base<coord_type> rect_type; + + //-------------------------------------------------------------------- + rasterizer_sl_clip() : + m_clip_box(0,0,0,0), + m_x1(0), + m_y1(0), + m_f1(0), + m_clipping(false) + {} + + //-------------------------------------------------------------------- + void reset_clipping() + { + m_clipping = false; + } + + //-------------------------------------------------------------------- + void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2) + { + m_clip_box = rect_type(x1, y1, x2, y2); + m_clip_box.normalize(); + m_clipping = true; + } + + //-------------------------------------------------------------------- + void move_to(coord_type x1, coord_type y1) + { + m_x1 = x1; + m_y1 = y1; + if(m_clipping) m_f1 = clipping_flags(x1, y1, m_clip_box); + } + + private: + //------------------------------------------------------------------------ + template<class Rasterizer> + AGG_INLINE void line_clip_y(Rasterizer& ras, + coord_type x1, coord_type y1, + coord_type x2, coord_type y2, + unsigned f1, unsigned f2) const + { + f1 &= 10; + f2 &= 10; + if((f1 | f2) == 0) + { + // Fully visible + ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2)); + } + else + { + if(f1 == f2) + { + // Invisible by Y + return; + } + + coord_type tx1 = x1; + coord_type ty1 = y1; + coord_type tx2 = x2; + coord_type ty2 = y2; + + if(f1 & 8) // y1 < clip.y1 + { + tx1 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1); + ty1 = m_clip_box.y1; + } + + if(f1 & 2) // y1 > clip.y2 + { + tx1 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1); + ty1 = m_clip_box.y2; + } + + if(f2 & 8) // y2 < clip.y1 + { + tx2 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1); + ty2 = m_clip_box.y1; + } + + if(f2 & 2) // y2 > clip.y2 + { + tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1); + ty2 = m_clip_box.y2; + } + ras.line(Conv::xi(tx1), Conv::yi(ty1), + Conv::xi(tx2), Conv::yi(ty2)); + } + } + + + public: + //-------------------------------------------------------------------- + template<class Rasterizer> + void line_to(Rasterizer& ras, coord_type x2, coord_type y2) + { + if(m_clipping) + { + unsigned f2 = clipping_flags(x2, y2, m_clip_box); + + if((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0) + { + // Invisible by Y + m_x1 = x2; + m_y1 = y2; + m_f1 = f2; + return; + } + + coord_type x1 = m_x1; + coord_type y1 = m_y1; + unsigned f1 = m_f1; + coord_type y3, y4; + unsigned f3, f4; + + switch(((f1 & 5) << 1) | (f2 & 5)) + { + case 0: // Visible by X + line_clip_y(ras, x1, y1, x2, y2, f1, f2); + break; + + case 1: // x2 > clip.x2 + y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + line_clip_y(ras, x1, y1, m_clip_box.x2, y3, f1, f3); + line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x2, y2, f3, f2); + break; + + case 2: // x1 > clip.x2 + y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3); + line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2); + break; + + case 3: // x1 > clip.x2 && x2 > clip.x2 + line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y2, f1, f2); + break; + + case 4: // x2 < clip.x1 + y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + line_clip_y(ras, x1, y1, m_clip_box.x1, y3, f1, f3); + line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x1, y2, f3, f2); + break; + + case 6: // x1 > clip.x2 && x2 < clip.x1 + y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1); + y4 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + f4 = clipping_flags_y(y4, m_clip_box); + line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3); + line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x1, y4, f3, f4); + line_clip_y(ras, m_clip_box.x1, y4, m_clip_box.x1, y2, f4, f2); + break; + + case 8: // x1 < clip.x1 + y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3); + line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2); + break; + + case 9: // x1 < clip.x1 && x2 > clip.x2 + y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1); + y4 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + f4 = clipping_flags_y(y4, m_clip_box); + line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3); + line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x2, y4, f3, f4); + line_clip_y(ras, m_clip_box.x2, y4, m_clip_box.x2, y2, f4, f2); + break; + + case 12: // x1 < clip.x1 && x2 < clip.x1 + line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2); + break; + } + m_f1 = f2; + } + else + { + ras.line(Conv::xi(m_x1), Conv::yi(m_y1), + Conv::xi(x2), Conv::yi(y2)); + } + m_x1 = x2; + m_y1 = y2; + } + + + private: + rect_type m_clip_box; + coord_type m_x1; + coord_type m_y1; + unsigned m_f1; + bool m_clipping; + }; + + + + + //---------------------------------------------------rasterizer_sl_no_clip + class rasterizer_sl_no_clip + { + public: + typedef ras_conv_int conv_type; + typedef int coord_type; + + rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {} + + void reset_clipping() {} + void clip_box(coord_type, coord_type, coord_type, coord_type) {} + void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; } + + template<class Rasterizer> + void line_to(Rasterizer& ras, coord_type x2, coord_type y2) + { + ras.line(m_x1, m_y1, x2, y2); + m_x1 = x2; + m_y1 = y2; + } + + private: + int m_x1, m_y1; + }; + + + // -----rasterizer_sl_clip_int + // -----rasterizer_sl_clip_int_sat + // -----rasterizer_sl_clip_int_3x + // -----rasterizer_sl_clip_dbl + // -----rasterizer_sl_clip_dbl_3x + //------------------------------------------------------------------------ + typedef rasterizer_sl_clip<ras_conv_int> rasterizer_sl_clip_int; + typedef rasterizer_sl_clip<ras_conv_int_sat> rasterizer_sl_clip_int_sat; + typedef rasterizer_sl_clip<ras_conv_int_3x> rasterizer_sl_clip_int_3x; + typedef rasterizer_sl_clip<ras_conv_dbl> rasterizer_sl_clip_dbl; + typedef rasterizer_sl_clip<ras_conv_dbl_3x> rasterizer_sl_clip_dbl_3x; + + +} + +#endif diff --git a/include/agg_renderer_base.h b/include/agg_renderer_base.h new file mode 100644 index 0000000..527c62f --- /dev/null +++ b/include/agg_renderer_base.h @@ -0,0 +1,731 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class renderer_base +// +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERER_BASE_INCLUDED +#define AGG_RENDERER_BASE_INCLUDED + +#include "agg_basics.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + + //-----------------------------------------------------------renderer_base + template<class PixelFormat> class renderer_base + { + public: + typedef PixelFormat pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::row_data row_data; + + //-------------------------------------------------------------------- + renderer_base() : m_ren(0), m_clip_box(1, 1, 0, 0) {} + explicit renderer_base(pixfmt_type& ren) : + m_ren(&ren), + m_clip_box(0, 0, ren.width() - 1, ren.height() - 1) + {} + void attach(pixfmt_type& ren) + { + m_ren = &ren; + m_clip_box = rect_i(0, 0, ren.width() - 1, ren.height() - 1); + } + + //-------------------------------------------------------------------- + const pixfmt_type& ren() const { return *m_ren; } + pixfmt_type& ren() { return *m_ren; } + + //-------------------------------------------------------------------- + unsigned width() const { return m_ren->width(); } + unsigned height() const { return m_ren->height(); } + + //-------------------------------------------------------------------- + bool clip_box(int x1, int y1, int x2, int y2) + { + rect_i cb(x1, y1, x2, y2); + cb.normalize(); + if(cb.clip(rect_i(0, 0, width() - 1, height() - 1))) + { + m_clip_box = cb; + return true; + } + m_clip_box.x1 = 1; + m_clip_box.y1 = 1; + m_clip_box.x2 = 0; + m_clip_box.y2 = 0; + return false; + } + + //-------------------------------------------------------------------- + void reset_clipping(bool visibility) + { + if(visibility) + { + m_clip_box.x1 = 0; + m_clip_box.y1 = 0; + m_clip_box.x2 = width() - 1; + m_clip_box.y2 = height() - 1; + } + else + { + m_clip_box.x1 = 1; + m_clip_box.y1 = 1; + m_clip_box.x2 = 0; + m_clip_box.y2 = 0; + } + } + + //-------------------------------------------------------------------- + void clip_box_naked(int x1, int y1, int x2, int y2) + { + m_clip_box.x1 = x1; + m_clip_box.y1 = y1; + m_clip_box.x2 = x2; + m_clip_box.y2 = y2; + } + + //-------------------------------------------------------------------- + bool inbox(int x, int y) const + { + return x >= m_clip_box.x1 && y >= m_clip_box.y1 && + x <= m_clip_box.x2 && y <= m_clip_box.y2; + } + + //-------------------------------------------------------------------- + const rect_i& clip_box() const { return m_clip_box; } + int xmin() const { return m_clip_box.x1; } + int ymin() const { return m_clip_box.y1; } + int xmax() const { return m_clip_box.x2; } + int ymax() const { return m_clip_box.y2; } + + //-------------------------------------------------------------------- + const rect_i& bounding_clip_box() const { return m_clip_box; } + int bounding_xmin() const { return m_clip_box.x1; } + int bounding_ymin() const { return m_clip_box.y1; } + int bounding_xmax() const { return m_clip_box.x2; } + int bounding_ymax() const { return m_clip_box.y2; } + + //-------------------------------------------------------------------- + void clear(const color_type& c) + { + unsigned y; + if(width()) + { + for(y = 0; y < height(); y++) + { + m_ren->copy_hline(0, y, width(), c); + } + } + } + + + //-------------------------------------------------------------------- + void fill(const color_type& c) + { + unsigned y; + if(width()) + { + for(y = 0; y < height(); y++) + { + m_ren->blend_hline(0, y, width(), c, cover_mask); + } + } + } + + //-------------------------------------------------------------------- + void copy_pixel(int x, int y, const color_type& c) + { + if(inbox(x, y)) + { + m_ren->copy_pixel(x, y, c); + } + } + + //-------------------------------------------------------------------- + void blend_pixel(int x, int y, const color_type& c, cover_type cover) + { + if(inbox(x, y)) + { + m_ren->blend_pixel(x, y, c, cover); + } + } + + //-------------------------------------------------------------------- + color_type pixel(int x, int y) const + { + return inbox(x, y) ? + m_ren->pixel(x, y) : + color_type::no_color(); + } + + //-------------------------------------------------------------------- + void copy_hline(int x1, int y, int x2, const color_type& c) + { + if(x1 > x2) { int t = x2; x2 = x1; x1 = t; } + if(y > ymax()) return; + if(y < ymin()) return; + if(x1 > xmax()) return; + if(x2 < xmin()) return; + + if(x1 < xmin()) x1 = xmin(); + if(x2 > xmax()) x2 = xmax(); + + m_ren->copy_hline(x1, y, x2 - x1 + 1, c); + } + + //-------------------------------------------------------------------- + void copy_vline(int x, int y1, int y2, const color_type& c) + { + if(y1 > y2) { int t = y2; y2 = y1; y1 = t; } + if(x > xmax()) return; + if(x < xmin()) return; + if(y1 > ymax()) return; + if(y2 < ymin()) return; + + if(y1 < ymin()) y1 = ymin(); + if(y2 > ymax()) y2 = ymax(); + + m_ren->copy_vline(x, y1, y2 - y1 + 1, c); + } + + //-------------------------------------------------------------------- + void blend_hline(int x1, int y, int x2, + const color_type& c, cover_type cover) + { + if(x1 > x2) { int t = x2; x2 = x1; x1 = t; } + if(y > ymax()) return; + if(y < ymin()) return; + if(x1 > xmax()) return; + if(x2 < xmin()) return; + + if(x1 < xmin()) x1 = xmin(); + if(x2 > xmax()) x2 = xmax(); + + m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover); + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y1, int y2, + const color_type& c, cover_type cover) + { + if(y1 > y2) { int t = y2; y2 = y1; y1 = t; } + if(x > xmax()) return; + if(x < xmin()) return; + if(y1 > ymax()) return; + if(y2 < ymin()) return; + + if(y1 < ymin()) y1 = ymin(); + if(y2 > ymax()) y2 = ymax(); + + m_ren->blend_vline(x, y1, y2 - y1 + 1, c, cover); + } + + + //-------------------------------------------------------------------- + void copy_bar(int x1, int y1, int x2, int y2, const color_type& c) + { + rect_i rc(x1, y1, x2, y2); + rc.normalize(); + if(rc.clip(clip_box())) + { + int y; + for(y = rc.y1; y <= rc.y2; y++) + { + m_ren->copy_hline(rc.x1, y, unsigned(rc.x2 - rc.x1 + 1), c); + } + } + } + + //-------------------------------------------------------------------- + void blend_bar(int x1, int y1, int x2, int y2, + const color_type& c, cover_type cover) + { + rect_i rc(x1, y1, x2, y2); + rc.normalize(); + if(rc.clip(clip_box())) + { + int y; + for(y = rc.y1; y <= rc.y2; y++) + { + m_ren->blend_hline(rc.x1, + y, + unsigned(rc.x2 - rc.x1 + 1), + c, + cover); + } + } + } + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, int len, + const color_type& c, + const cover_type* covers) + { + if(y > ymax()) return; + if(y < ymin()) return; + + if(x < xmin()) + { + len -= xmin() - x; + if(len <= 0) return; + covers += xmin() - x; + x = xmin(); + } + if(x + len > xmax()) + { + len = xmax() - x + 1; + if(len <= 0) return; + } + m_ren->blend_solid_hspan(x, y, len, c, covers); + } + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, int len, + const color_type& c, + const cover_type* covers) + { + if(x > xmax()) return; + if(x < xmin()) return; + + if(y < ymin()) + { + len -= ymin() - y; + if(len <= 0) return; + covers += ymin() - y; + y = ymin(); + } + if(y + len > ymax()) + { + len = ymax() - y + 1; + if(len <= 0) return; + } + m_ren->blend_solid_vspan(x, y, len, c, covers); + } + + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, int len, const color_type* colors) + { + if(y > ymax()) return; + if(y < ymin()) return; + + if(x < xmin()) + { + int d = xmin() - x; + len -= d; + if(len <= 0) return; + colors += d; + x = xmin(); + } + if(x + len > xmax()) + { + len = xmax() - x + 1; + if(len <= 0) return; + } + m_ren->copy_color_hspan(x, y, len, colors); + } + + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, int len, const color_type* colors) + { + if(x > xmax()) return; + if(x < xmin()) return; + + if(y < ymin()) + { + int d = ymin() - y; + len -= d; + if(len <= 0) return; + colors += d; + y = ymin(); + } + if(y + len > ymax()) + { + len = ymax() - y + 1; + if(len <= 0) return; + } + m_ren->copy_color_vspan(x, y, len, colors); + } + + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, int len, + const color_type* colors, + const cover_type* covers, + cover_type cover = agg::cover_full) + { + if(y > ymax()) return; + if(y < ymin()) return; + + if(x < xmin()) + { + int d = xmin() - x; + len -= d; + if(len <= 0) return; + if(covers) covers += d; + colors += d; + x = xmin(); + } + if(x + len > xmax()) + { + len = xmax() - x + 1; + if(len <= 0) return; + } + m_ren->blend_color_hspan(x, y, len, colors, covers, cover); + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, int len, + const color_type* colors, + const cover_type* covers, + cover_type cover = agg::cover_full) + { + if(x > xmax()) return; + if(x < xmin()) return; + + if(y < ymin()) + { + int d = ymin() - y; + len -= d; + if(len <= 0) return; + if(covers) covers += d; + colors += d; + y = ymin(); + } + if(y + len > ymax()) + { + len = ymax() - y + 1; + if(len <= 0) return; + } + m_ren->blend_color_vspan(x, y, len, colors, covers, cover); + } + + //-------------------------------------------------------------------- + rect_i clip_rect_area(rect_i& dst, rect_i& src, int wsrc, int hsrc) const + { + rect_i rc(0,0,0,0); + rect_i cb = clip_box(); + ++cb.x2; + ++cb.y2; + + if(src.x1 < 0) + { + dst.x1 -= src.x1; + src.x1 = 0; + } + if(src.y1 < 0) + { + dst.y1 -= src.y1; + src.y1 = 0; + } + + if(src.x2 > wsrc) src.x2 = wsrc; + if(src.y2 > hsrc) src.y2 = hsrc; + + if(dst.x1 < cb.x1) + { + src.x1 += cb.x1 - dst.x1; + dst.x1 = cb.x1; + } + if(dst.y1 < cb.y1) + { + src.y1 += cb.y1 - dst.y1; + dst.y1 = cb.y1; + } + + if(dst.x2 > cb.x2) dst.x2 = cb.x2; + if(dst.y2 > cb.y2) dst.y2 = cb.y2; + + rc.x2 = dst.x2 - dst.x1; + rc.y2 = dst.y2 - dst.y1; + + if(rc.x2 > src.x2 - src.x1) rc.x2 = src.x2 - src.x1; + if(rc.y2 > src.y2 - src.y1) rc.y2 = src.y2 - src.y1; + return rc; + } + + //-------------------------------------------------------------------- + template<class RenBuf> + void copy_from(const RenBuf& src, + const rect_i* rect_src_ptr = 0, + int dx = 0, + int dy = 0) + { + rect_i rsrc(0, 0, src.width(), src.height()); + if(rect_src_ptr) + { + rsrc.x1 = rect_src_ptr->x1; + rsrc.y1 = rect_src_ptr->y1; + rsrc.x2 = rect_src_ptr->x2 + 1; + rsrc.y2 = rect_src_ptr->y2 + 1; + } + + // Version with xdst, ydst (absolute positioning) + //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1); + + // Version with dx, dy (relative positioning) + rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy); + + rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height()); + + if(rc.x2 > 0) + { + int incy = 1; + if(rdst.y1 > rsrc.y1) + { + rsrc.y1 += rc.y2 - 1; + rdst.y1 += rc.y2 - 1; + incy = -1; + } + while(rc.y2 > 0) + { + m_ren->copy_from(src, + rdst.x1, rdst.y1, + rsrc.x1, rsrc.y1, + rc.x2); + rdst.y1 += incy; + rsrc.y1 += incy; + --rc.y2; + } + } + } + + //-------------------------------------------------------------------- + template<class SrcPixelFormatRenderer> + void blend_from(const SrcPixelFormatRenderer& src, + const rect_i* rect_src_ptr = 0, + int dx = 0, + int dy = 0, + cover_type cover = agg::cover_full) + { + rect_i rsrc(0, 0, src.width(), src.height()); + if(rect_src_ptr) + { + rsrc.x1 = rect_src_ptr->x1; + rsrc.y1 = rect_src_ptr->y1; + rsrc.x2 = rect_src_ptr->x2 + 1; + rsrc.y2 = rect_src_ptr->y2 + 1; + } + + // Version with xdst, ydst (absolute positioning) + //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1); + + // Version with dx, dy (relative positioning) + rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy); + rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height()); + + if(rc.x2 > 0) + { + int incy = 1; + if(rdst.y1 > rsrc.y1) + { + rsrc.y1 += rc.y2 - 1; + rdst.y1 += rc.y2 - 1; + incy = -1; + } + while(rc.y2 > 0) + { + typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1); + if(rw.ptr) + { + int x1src = rsrc.x1; + int x1dst = rdst.x1; + int len = rc.x2; + if(rw.x1 > x1src) + { + x1dst += rw.x1 - x1src; + len -= rw.x1 - x1src; + x1src = rw.x1; + } + if(len > 0) + { + if(x1src + len-1 > rw.x2) + { + len -= x1src + len - rw.x2 - 1; + } + if(len > 0) + { + m_ren->blend_from(src, + x1dst, rdst.y1, + x1src, rsrc.y1, + len, + cover); + } + } + } + rdst.y1 += incy; + rsrc.y1 += incy; + --rc.y2; + } + } + } + + //-------------------------------------------------------------------- + template<class SrcPixelFormatRenderer> + void blend_from_color(const SrcPixelFormatRenderer& src, + const color_type& color, + const rect_i* rect_src_ptr = 0, + int dx = 0, + int dy = 0, + cover_type cover = agg::cover_full) + { + rect_i rsrc(0, 0, src.width(), src.height()); + if(rect_src_ptr) + { + rsrc.x1 = rect_src_ptr->x1; + rsrc.y1 = rect_src_ptr->y1; + rsrc.x2 = rect_src_ptr->x2 + 1; + rsrc.y2 = rect_src_ptr->y2 + 1; + } + + // Version with xdst, ydst (absolute positioning) + //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1); + + // Version with dx, dy (relative positioning) + rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy); + rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height()); + + if(rc.x2 > 0) + { + int incy = 1; + if(rdst.y1 > rsrc.y1) + { + rsrc.y1 += rc.y2 - 1; + rdst.y1 += rc.y2 - 1; + incy = -1; + } + while(rc.y2 > 0) + { + typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1); + if(rw.ptr) + { + int x1src = rsrc.x1; + int x1dst = rdst.x1; + int len = rc.x2; + if(rw.x1 > x1src) + { + x1dst += rw.x1 - x1src; + len -= rw.x1 - x1src; + x1src = rw.x1; + } + if(len > 0) + { + if(x1src + len-1 > rw.x2) + { + len -= x1src + len - rw.x2 - 1; + } + if(len > 0) + { + m_ren->blend_from_color(src, + color, + x1dst, rdst.y1, + x1src, rsrc.y1, + len, + cover); + } + } + } + rdst.y1 += incy; + rsrc.y1 += incy; + --rc.y2; + } + } + } + + //-------------------------------------------------------------------- + template<class SrcPixelFormatRenderer> + void blend_from_lut(const SrcPixelFormatRenderer& src, + const color_type* color_lut, + const rect_i* rect_src_ptr = 0, + int dx = 0, + int dy = 0, + cover_type cover = agg::cover_full) + { + rect_i rsrc(0, 0, src.width(), src.height()); + if(rect_src_ptr) + { + rsrc.x1 = rect_src_ptr->x1; + rsrc.y1 = rect_src_ptr->y1; + rsrc.x2 = rect_src_ptr->x2 + 1; + rsrc.y2 = rect_src_ptr->y2 + 1; + } + + // Version with xdst, ydst (absolute positioning) + //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1); + + // Version with dx, dy (relative positioning) + rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy); + rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height()); + + if(rc.x2 > 0) + { + int incy = 1; + if(rdst.y1 > rsrc.y1) + { + rsrc.y1 += rc.y2 - 1; + rdst.y1 += rc.y2 - 1; + incy = -1; + } + while(rc.y2 > 0) + { + typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1); + if(rw.ptr) + { + int x1src = rsrc.x1; + int x1dst = rdst.x1; + int len = rc.x2; + if(rw.x1 > x1src) + { + x1dst += rw.x1 - x1src; + len -= rw.x1 - x1src; + x1src = rw.x1; + } + if(len > 0) + { + if(x1src + len-1 > rw.x2) + { + len -= x1src + len - rw.x2 - 1; + } + if(len > 0) + { + m_ren->blend_from_lut(src, + color_lut, + x1dst, rdst.y1, + x1src, rsrc.y1, + len, + cover); + } + } + } + rdst.y1 += incy; + rsrc.y1 += incy; + --rc.y2; + } + } + } + + private: + pixfmt_type* m_ren; + rect_i m_clip_box; + }; + + +} + +#endif diff --git a/include/agg_renderer_markers.h b/include/agg_renderer_markers.h new file mode 100644 index 0000000..6ff0534 --- /dev/null +++ b/include/agg_renderer_markers.h @@ -0,0 +1,711 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class renderer_markers +// +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERER_MARKERS_INCLUDED +#define AGG_RENDERER_MARKERS_INCLUDED + +#include "agg_basics.h" +#include "agg_renderer_primitives.h" + +namespace agg +{ + + //---------------------------------------------------------------marker_e + enum marker_e + { + marker_square, + marker_diamond, + marker_circle, + marker_crossed_circle, + marker_semiellipse_left, + marker_semiellipse_right, + marker_semiellipse_up, + marker_semiellipse_down, + marker_triangle_left, + marker_triangle_right, + marker_triangle_up, + marker_triangle_down, + marker_four_rays, + marker_cross, + marker_x, + marker_dash, + marker_dot, + marker_pixel, + + end_of_markers + }; + + + + //--------------------------------------------------------renderer_markers + template<class BaseRenderer> class renderer_markers : + public renderer_primitives<BaseRenderer> + { + public: + typedef renderer_primitives<BaseRenderer> base_type; + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; + + //-------------------------------------------------------------------- + renderer_markers(base_ren_type& rbuf) : + base_type(rbuf) + {} + + //-------------------------------------------------------------------- + bool visible(int x, int y, int r) const + { + rect_i rc(x-r, y-r, x+y, y+r); + return rc.clip(base_type::ren().bounding_clip_box()); + } + + //-------------------------------------------------------------------- + void square(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) base_type::outlined_rectangle(x-r, y-r, x+r, y+r); + else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + + //-------------------------------------------------------------------- + void diamond(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int dy = -r; + int dx = 0; + do + { + base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full); + + if(dx) + { + base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full); + base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full); + } + ++dy; + ++dx; + } + while(dy <= 0); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + //-------------------------------------------------------------------- + void circle(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) base_type::outlined_ellipse(x, y, r, r); + else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + + + + //-------------------------------------------------------------------- + void crossed_circle(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + base_type::outlined_ellipse(x, y, r, r); + int r6 = r + (r >> 1); + if(r <= 2) r6++; + r >>= 1; + base_type::ren().blend_hline(x-r6, y, x-r, base_type::line_color(), cover_full); + base_type::ren().blend_hline(x+r, y, x+r6, base_type::line_color(), cover_full); + base_type::ren().blend_vline(x, y-r6, y-r, base_type::line_color(), cover_full); + base_type::ren().blend_vline(x, y+r, y+r6, base_type::line_color(), cover_full); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //------------------------------------------------------------------------ + void semiellipse_left(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int r8 = r * 4 / 5; + int dy = -r; + int dx = 0; + ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8); + do + { + dx += ei.dx(); + dy += ei.dy(); + + base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full); + + if(ei.dy() && dx) + { + base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); + } + ++ei; + } + while(dy < r8); + base_type::ren().blend_vline(x+dy, y-dx, y+dx, base_type::line_color(), cover_full); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //-------------------------------------------------------------------- + void semiellipse_right(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int r8 = r * 4 / 5; + int dy = -r; + int dx = 0; + ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8); + do + { + dx += ei.dx(); + dy += ei.dy(); + + base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full); + + if(ei.dy() && dx) + { + base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); + } + ++ei; + } + while(dy < r8); + base_type::ren().blend_vline(x-dy, y-dx, y+dx, base_type::line_color(), cover_full); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //-------------------------------------------------------------------- + void semiellipse_up(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int r8 = r * 4 / 5; + int dy = -r; + int dx = 0; + ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8); + do + { + dx += ei.dx(); + dy += ei.dy(); + + base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full); + + if(ei.dy() && dx) + { + base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full); + } + ++ei; + } + while(dy < r8); + base_type::ren().blend_hline(x-dx, y-dy-1, x+dx, base_type::line_color(), cover_full); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //-------------------------------------------------------------------- + void semiellipse_down(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int r8 = r * 4 / 5; + int dy = -r; + int dx = 0; + ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8); + do + { + dx += ei.dx(); + dy += ei.dy(); + + base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full); + + if(ei.dy() && dx) + { + base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full); + } + ++ei; + } + while(dy < r8); + base_type::ren().blend_hline(x-dx, y+dy+1, x+dx, base_type::line_color(), cover_full); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //-------------------------------------------------------------------- + void triangle_left(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int dy = -r; + int dx = 0; + int flip = 0; + int r6 = r * 3 / 5; + do + { + base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full); + + if(dx) + { + base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); + } + ++dy; + dx += flip; + flip ^= 1; + } + while(dy < r6); + base_type::ren().blend_vline(x+dy, y-dx, y+dx, base_type::line_color(), cover_full); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //-------------------------------------------------------------------- + void triangle_right(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int dy = -r; + int dx = 0; + int flip = 0; + int r6 = r * 3 / 5; + do + { + base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full); + + if(dx) + { + base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); + } + ++dy; + dx += flip; + flip ^= 1; + } + while(dy < r6); + base_type::ren().blend_vline(x-dy, y-dx, y+dx, base_type::line_color(), cover_full); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //-------------------------------------------------------------------- + void triangle_up(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int dy = -r; + int dx = 0; + int flip = 0; + int r6 = r * 3 / 5; + do + { + base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full); + + if(dx) + { + base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full); + } + ++dy; + dx += flip; + flip ^= 1; + } + while(dy < r6); + base_type::ren().blend_hline(x-dx, y-dy, x+dx, base_type::line_color(), cover_full); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //-------------------------------------------------------------------- + void triangle_down(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int dy = -r; + int dx = 0; + int flip = 0; + int r6 = r * 3 / 5; + do + { + base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full); + + if(dx) + { + base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full); + } + ++dy; + dx += flip; + flip ^= 1; + } + while(dy < r6); + base_type::ren().blend_hline(x-dx, y+dy, x+dx, base_type::line_color(), cover_full); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //-------------------------------------------------------------------- + void four_rays(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int dy = -r; + int dx = 0; + int flip = 0; + int r3 = -(r / 3); + do + { + base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full); + + if(dx) + { + base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full); + base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full); + base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); + base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full); + } + ++dy; + dx += flip; + flip ^= 1; + } + while(dy <= r3); + base_type::solid_rectangle(x+r3+1, y+r3+1, x-r3-1, y-r3-1); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //-------------------------------------------------------------------- + void cross(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + base_type::ren().blend_vline(x, y-r, y+r, base_type::line_color(), cover_full); + base_type::ren().blend_hline(x-r, y, x+r, base_type::line_color(), cover_full); + } + else + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + } + + + //-------------------------------------------------------------------- + void xing(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) + { + int dy = -r * 7 / 10; + do + { + base_type::ren().blend_pixel(x + dy, y + dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x - dy, y + dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x + dy, y - dy, base_type::line_color(), cover_full); + base_type::ren().blend_pixel(x - dy, y - dy, base_type::line_color(), cover_full); + ++dy; + } + while(dy < 0); + } + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + + + //-------------------------------------------------------------------- + void dash(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) base_type::ren().blend_hline(x-r, y, x+r, base_type::line_color(), cover_full); + else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + + + //-------------------------------------------------------------------- + void dot(int x, int y, int r) + { + if(visible(x, y, r)) + { + if(r) base_type::solid_ellipse(x, y, r, r); + else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + } + + //-------------------------------------------------------------------- + void pixel(int x, int y, int) + { + base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full); + } + + //-------------------------------------------------------------------- + void marker(int x, int y, int r, marker_e type) + { + switch(type) + { + case marker_square: square(x, y, r); break; + case marker_diamond: diamond(x, y, r); break; + case marker_circle: circle(x, y, r); break; + case marker_crossed_circle: crossed_circle(x, y, r); break; + case marker_semiellipse_left: semiellipse_left(x, y, r); break; + case marker_semiellipse_right: semiellipse_right(x, y, r); break; + case marker_semiellipse_up: semiellipse_up(x, y, r); break; + case marker_semiellipse_down: semiellipse_down(x, y, r); break; + case marker_triangle_left: triangle_left(x, y, r); break; + case marker_triangle_right: triangle_right(x, y, r); break; + case marker_triangle_up: triangle_up(x, y, r); break; + case marker_triangle_down: triangle_down(x, y, r); break; + case marker_four_rays: four_rays(x, y, r); break; + case marker_cross: cross(x, y, r); break; + case marker_x: xing(x, y, r); break; + case marker_dash: dash(x, y, r); break; + case marker_dot: dot(x, y, r); break; + case marker_pixel: pixel(x, y, r); break; + case end_of_markers: break; + } + } + + + //-------------------------------------------------------------------- + template<class T> + void markers(int n, const T* x, const T* y, T r, marker_e type) + { + if(n <= 0) return; + if(r == 0) + { + do + { + base_type::ren().blend_pixel(int(*x), int(*y), base_type::fill_color(), cover_full); + ++x; + ++y; + } + while(--n); + return; + } + + switch(type) + { + case marker_square: do { square (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_diamond: do { diamond (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_circle: do { circle (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_crossed_circle: do { crossed_circle (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_semiellipse_left: do { semiellipse_left (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_semiellipse_right: do { semiellipse_right(int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_semiellipse_up: do { semiellipse_up (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_semiellipse_down: do { semiellipse_down (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_triangle_left: do { triangle_left (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_triangle_right: do { triangle_right (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_triangle_up: do { triangle_up (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_triangle_down: do { triangle_down (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_four_rays: do { four_rays (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_cross: do { cross (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_x: do { xing (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_dash: do { dash (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_dot: do { dot (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case marker_pixel: do { pixel (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break; + case end_of_markers: break; + } + } + + //-------------------------------------------------------------------- + template<class T> + void markers(int n, const T* x, const T* y, const T* r, marker_e type) + { + if(n <= 0) return; + switch(type) + { + case marker_square: do { square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_diamond: do { diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_circle: do { circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_crossed_circle: do { crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_semiellipse_left: do { semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_semiellipse_right: do { semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_semiellipse_up: do { semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_semiellipse_down: do { semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_triangle_left: do { triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_triangle_right: do { triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_triangle_up: do { triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_triangle_down: do { triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_four_rays: do { four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_cross: do { cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_x: do { xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_dash: do { dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_dot: do { dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case marker_pixel: do { pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break; + case end_of_markers: break; + } + } + + //-------------------------------------------------------------------- + template<class T> + void markers(int n, const T* x, const T* y, const T* r, const color_type* fc, marker_e type) + { + if(n <= 0) return; + switch(type) + { + case marker_square: do { base_type::fill_color(*fc); square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_diamond: do { base_type::fill_color(*fc); diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_circle: do { base_type::fill_color(*fc); circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_crossed_circle: do { base_type::fill_color(*fc); crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_semiellipse_left: do { base_type::fill_color(*fc); semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_semiellipse_right: do { base_type::fill_color(*fc); semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_semiellipse_up: do { base_type::fill_color(*fc); semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_semiellipse_down: do { base_type::fill_color(*fc); semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_triangle_left: do { base_type::fill_color(*fc); triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_triangle_right: do { base_type::fill_color(*fc); triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_triangle_up: do { base_type::fill_color(*fc); triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_triangle_down: do { base_type::fill_color(*fc); triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_four_rays: do { base_type::fill_color(*fc); four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_cross: do { base_type::fill_color(*fc); cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_x: do { base_type::fill_color(*fc); xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_dash: do { base_type::fill_color(*fc); dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_dot: do { base_type::fill_color(*fc); dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case marker_pixel: do { base_type::fill_color(*fc); pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break; + case end_of_markers: break; + } + } + + //-------------------------------------------------------------------- + template<class T> + void markers(int n, const T* x, const T* y, const T* r, const color_type* fc, const color_type* lc, marker_e type) + { + if(n <= 0) return; + switch(type) + { + case marker_square: do { base_type::fill_color(*fc); base_type::line_color(*lc); square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_diamond: do { base_type::fill_color(*fc); base_type::line_color(*lc); diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_circle: do { base_type::fill_color(*fc); base_type::line_color(*lc); circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_crossed_circle: do { base_type::fill_color(*fc); base_type::line_color(*lc); crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_semiellipse_left: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_semiellipse_right: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_semiellipse_up: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_semiellipse_down: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_triangle_left: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_triangle_right: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_triangle_up: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_triangle_down: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_four_rays: do { base_type::fill_color(*fc); base_type::line_color(*lc); four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_cross: do { base_type::fill_color(*fc); base_type::line_color(*lc); cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_x: do { base_type::fill_color(*fc); base_type::line_color(*lc); xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_dash: do { base_type::fill_color(*fc); base_type::line_color(*lc); dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_dot: do { base_type::fill_color(*fc); base_type::line_color(*lc); dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case marker_pixel: do { base_type::fill_color(*fc); base_type::line_color(*lc); pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break; + case end_of_markers: break; + } + } + }; + +} + +#endif diff --git a/include/agg_renderer_mclip.h b/include/agg_renderer_mclip.h new file mode 100644 index 0000000..96a7d4e --- /dev/null +++ b/include/agg_renderer_mclip.h @@ -0,0 +1,349 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class renderer_mclip +// +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERER_MCLIP_INCLUDED +#define AGG_RENDERER_MCLIP_INCLUDED + +#include "agg_basics.h" +#include "agg_array.h" +#include "agg_renderer_base.h" + +namespace agg +{ + + //----------------------------------------------------------renderer_mclip + template<class PixelFormat> class renderer_mclip + { + public: + typedef PixelFormat pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::row_data row_data; + typedef renderer_base<pixfmt_type> base_ren_type; + + //-------------------------------------------------------------------- + explicit renderer_mclip(pixfmt_type& pixf) : + m_ren(pixf), + m_curr_cb(0), + m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax()) + {} + void attach(pixfmt_type& pixf) + { + m_ren.attach(pixf); + reset_clipping(true); + } + + //-------------------------------------------------------------------- + const pixfmt_type& ren() const { return m_ren.ren(); } + pixfmt_type& ren() { return m_ren.ren(); } + + //-------------------------------------------------------------------- + unsigned width() const { return m_ren.width(); } + unsigned height() const { return m_ren.height(); } + + //-------------------------------------------------------------------- + const rect_i& clip_box() const { return m_ren.clip_box(); } + int xmin() const { return m_ren.xmin(); } + int ymin() const { return m_ren.ymin(); } + int xmax() const { return m_ren.xmax(); } + int ymax() const { return m_ren.ymax(); } + + //-------------------------------------------------------------------- + const rect_i& bounding_clip_box() const { return m_bounds; } + int bounding_xmin() const { return m_bounds.x1; } + int bounding_ymin() const { return m_bounds.y1; } + int bounding_xmax() const { return m_bounds.x2; } + int bounding_ymax() const { return m_bounds.y2; } + + //-------------------------------------------------------------------- + void first_clip_box() + { + m_curr_cb = 0; + if(m_clip.size()) + { + const rect_i& cb = m_clip[0]; + m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2); + } + } + + //-------------------------------------------------------------------- + bool next_clip_box() + { + if(++m_curr_cb < m_clip.size()) + { + const rect_i& cb = m_clip[m_curr_cb]; + m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2); + return true; + } + return false; + } + + //-------------------------------------------------------------------- + void reset_clipping(bool visibility) + { + m_ren.reset_clipping(visibility); + m_clip.remove_all(); + m_curr_cb = 0; + m_bounds = m_ren.clip_box(); + } + + //-------------------------------------------------------------------- + void add_clip_box(int x1, int y1, int x2, int y2) + { + rect_i cb(x1, y1, x2, y2); + cb.normalize(); + if(cb.clip(rect_i(0, 0, width() - 1, height() - 1))) + { + m_clip.add(cb); + if(cb.x1 < m_bounds.x1) m_bounds.x1 = cb.x1; + if(cb.y1 < m_bounds.y1) m_bounds.y1 = cb.y1; + if(cb.x2 > m_bounds.x2) m_bounds.x2 = cb.x2; + if(cb.y2 > m_bounds.y2) m_bounds.y2 = cb.y2; + } + } + + //-------------------------------------------------------------------- + void clear(const color_type& c) + { + m_ren.clear(c); + } + + //-------------------------------------------------------------------- + void copy_pixel(int x, int y, const color_type& c) + { + first_clip_box(); + do + { + if(m_ren.inbox(x, y)) + { + m_ren.ren().copy_pixel(x, y, c); + break; + } + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_pixel(int x, int y, const color_type& c, cover_type cover) + { + first_clip_box(); + do + { + if(m_ren.inbox(x, y)) + { + m_ren.ren().blend_pixel(x, y, c, cover); + break; + } + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + color_type pixel(int x, int y) const + { + first_clip_box(); + do + { + if(m_ren.inbox(x, y)) + { + return m_ren.ren().pixel(x, y); + } + } + while(next_clip_box()); + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + void copy_hline(int x1, int y, int x2, const color_type& c) + { + first_clip_box(); + do + { + m_ren.copy_hline(x1, y, x2, c); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void copy_vline(int x, int y1, int y2, const color_type& c) + { + first_clip_box(); + do + { + m_ren.copy_vline(x, y1, y2, c); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_hline(int x1, int y, int x2, + const color_type& c, cover_type cover) + { + first_clip_box(); + do + { + m_ren.blend_hline(x1, y, x2, c, cover); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y1, int y2, + const color_type& c, cover_type cover) + { + first_clip_box(); + do + { + m_ren.blend_vline(x, y1, y2, c, cover); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void copy_bar(int x1, int y1, int x2, int y2, const color_type& c) + { + first_clip_box(); + do + { + m_ren.copy_bar(x1, y1, x2, y2, c); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_bar(int x1, int y1, int x2, int y2, + const color_type& c, cover_type cover) + { + first_clip_box(); + do + { + m_ren.blend_bar(x1, y1, x2, y2, c, cover); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, int len, + const color_type& c, const cover_type* covers) + { + first_clip_box(); + do + { + m_ren.blend_solid_hspan(x, y, len, c, covers); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, int len, + const color_type& c, const cover_type* covers) + { + first_clip_box(); + do + { + m_ren.blend_solid_vspan(x, y, len, c, covers); + } + while(next_clip_box()); + } + + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, int len, const color_type* colors) + { + first_clip_box(); + do + { + m_ren.copy_color_hspan(x, y, len, colors); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, int len, + const color_type* colors, + const cover_type* covers, + cover_type cover = cover_full) + { + first_clip_box(); + do + { + m_ren.blend_color_hspan(x, y, len, colors, covers, cover); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, int len, + const color_type* colors, + const cover_type* covers, + cover_type cover = cover_full) + { + first_clip_box(); + do + { + m_ren.blend_color_vspan(x, y, len, colors, covers, cover); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + void copy_from(const rendering_buffer& from, + const rect_i* rc=0, + int x_to=0, + int y_to=0) + { + first_clip_box(); + do + { + m_ren.copy_from(from, rc, x_to, y_to); + } + while(next_clip_box()); + } + + //-------------------------------------------------------------------- + template<class SrcPixelFormatRenderer> + void blend_from(const SrcPixelFormatRenderer& src, + const rect_i* rect_src_ptr = 0, + int dx = 0, + int dy = 0, + cover_type cover = cover_full) + { + first_clip_box(); + do + { + m_ren.blend_from(src, rect_src_ptr, dx, dy, cover); + } + while(next_clip_box()); + } + + + private: + renderer_mclip(const renderer_mclip<PixelFormat>&); + const renderer_mclip<PixelFormat>& + operator = (const renderer_mclip<PixelFormat>&); + + base_ren_type m_ren; + pod_bvector<rect_i, 4> m_clip; + unsigned m_curr_cb; + rect_i m_bounds; + }; + + +} + +#endif diff --git a/include/agg_renderer_outline_aa.h b/include/agg_renderer_outline_aa.h new file mode 100644 index 0000000..a1a248c --- /dev/null +++ b/include/agg_renderer_outline_aa.h @@ -0,0 +1,1838 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_RENDERER_OUTLINE_AA_INCLUDED +#define AGG_RENDERER_OUTLINE_AA_INCLUDED + +#include <cstdlib> +#include "agg_array.h" +#include "agg_math.h" +#include "agg_line_aa_basics.h" +#include "agg_dda_line.h" +#include "agg_ellipse_bresenham.h" +#include "agg_renderer_base.h" +#include "agg_gamma_functions.h" +#include "agg_clip_liang_barsky.h" + +namespace agg +{ + + //===================================================distance_interpolator0 + class distance_interpolator0 + { + public: + //--------------------------------------------------------------------- + distance_interpolator0() {} + distance_interpolator0(int x1, int y1, int x2, int y2, int x, int y) : + m_dx(line_mr(x2) - line_mr(x1)), + m_dy(line_mr(y2) - line_mr(y1)), + m_dist((line_mr(x + line_subpixel_scale/2) - line_mr(x2)) * m_dy - + (line_mr(y + line_subpixel_scale/2) - line_mr(y2)) * m_dx) + { + m_dx <<= line_mr_subpixel_shift; + m_dy <<= line_mr_subpixel_shift; + } + + //--------------------------------------------------------------------- + void inc_x() { m_dist += m_dy; } + int dist() const { return m_dist; } + + private: + //--------------------------------------------------------------------- + int m_dx; + int m_dy; + int m_dist; + }; + + //==================================================distance_interpolator00 + class distance_interpolator00 + { + public: + //--------------------------------------------------------------------- + distance_interpolator00() {} + distance_interpolator00(int xc, int yc, + int x1, int y1, int x2, int y2, + int x, int y) : + m_dx1(line_mr(x1) - line_mr(xc)), + m_dy1(line_mr(y1) - line_mr(yc)), + m_dx2(line_mr(x2) - line_mr(xc)), + m_dy2(line_mr(y2) - line_mr(yc)), + m_dist1((line_mr(x + line_subpixel_scale/2) - line_mr(x1)) * m_dy1 - + (line_mr(y + line_subpixel_scale/2) - line_mr(y1)) * m_dx1), + m_dist2((line_mr(x + line_subpixel_scale/2) - line_mr(x2)) * m_dy2 - + (line_mr(y + line_subpixel_scale/2) - line_mr(y2)) * m_dx2) + { + m_dx1 <<= line_mr_subpixel_shift; + m_dy1 <<= line_mr_subpixel_shift; + m_dx2 <<= line_mr_subpixel_shift; + m_dy2 <<= line_mr_subpixel_shift; + } + + //--------------------------------------------------------------------- + void inc_x() { m_dist1 += m_dy1; m_dist2 += m_dy2; } + int dist1() const { return m_dist1; } + int dist2() const { return m_dist2; } + + private: + //--------------------------------------------------------------------- + int m_dx1; + int m_dy1; + int m_dx2; + int m_dy2; + int m_dist1; + int m_dist2; + }; + + //===================================================distance_interpolator1 + class distance_interpolator1 + { + public: + //--------------------------------------------------------------------- + distance_interpolator1() {} + distance_interpolator1(int x1, int y1, int x2, int y2, int x, int y) : + m_dx(x2 - x1), + m_dy(y2 - y1), + m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) - + double(y + line_subpixel_scale/2 - y2) * double(m_dx))) + { + m_dx <<= line_subpixel_shift; + m_dy <<= line_subpixel_shift; + } + + //--------------------------------------------------------------------- + void inc_x() { m_dist += m_dy; } + void dec_x() { m_dist -= m_dy; } + void inc_y() { m_dist -= m_dx; } + void dec_y() { m_dist += m_dx; } + + //--------------------------------------------------------------------- + void inc_x(int dy) + { + m_dist += m_dy; + if(dy > 0) m_dist -= m_dx; + if(dy < 0) m_dist += m_dx; + } + + //--------------------------------------------------------------------- + void dec_x(int dy) + { + m_dist -= m_dy; + if(dy > 0) m_dist -= m_dx; + if(dy < 0) m_dist += m_dx; + } + + //--------------------------------------------------------------------- + void inc_y(int dx) + { + m_dist -= m_dx; + if(dx > 0) m_dist += m_dy; + if(dx < 0) m_dist -= m_dy; + } + + void dec_y(int dx) + //--------------------------------------------------------------------- + { + m_dist += m_dx; + if(dx > 0) m_dist += m_dy; + if(dx < 0) m_dist -= m_dy; + } + + //--------------------------------------------------------------------- + int dist() const { return m_dist; } + int dx() const { return m_dx; } + int dy() const { return m_dy; } + + private: + //--------------------------------------------------------------------- + int m_dx; + int m_dy; + int m_dist; + }; + + + + + + //===================================================distance_interpolator2 + class distance_interpolator2 + { + public: + //--------------------------------------------------------------------- + distance_interpolator2() {} + distance_interpolator2(int x1, int y1, int x2, int y2, + int sx, int sy, int x, int y) : + m_dx(x2 - x1), + m_dy(y2 - y1), + m_dx_start(line_mr(sx) - line_mr(x1)), + m_dy_start(line_mr(sy) - line_mr(y1)), + + m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) - + double(y + line_subpixel_scale/2 - y2) * double(m_dx))), + + m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start - + (line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start) + { + m_dx <<= line_subpixel_shift; + m_dy <<= line_subpixel_shift; + m_dx_start <<= line_mr_subpixel_shift; + m_dy_start <<= line_mr_subpixel_shift; + } + + distance_interpolator2(int x1, int y1, int x2, int y2, + int ex, int ey, int x, int y, int) : + m_dx(x2 - x1), + m_dy(y2 - y1), + m_dx_start(line_mr(ex) - line_mr(x2)), + m_dy_start(line_mr(ey) - line_mr(y2)), + + m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) - + double(y + line_subpixel_scale/2 - y2) * double(m_dx))), + + m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_start - + (line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_start) + { + m_dx <<= line_subpixel_shift; + m_dy <<= line_subpixel_shift; + m_dx_start <<= line_mr_subpixel_shift; + m_dy_start <<= line_mr_subpixel_shift; + } + + + //--------------------------------------------------------------------- + void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; } + void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; } + void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; } + void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; } + + //--------------------------------------------------------------------- + void inc_x(int dy) + { + m_dist += m_dy; + m_dist_start += m_dy_start; + if(dy > 0) + { + m_dist -= m_dx; + m_dist_start -= m_dx_start; + } + if(dy < 0) + { + m_dist += m_dx; + m_dist_start += m_dx_start; + } + } + + //--------------------------------------------------------------------- + void dec_x(int dy) + { + m_dist -= m_dy; + m_dist_start -= m_dy_start; + if(dy > 0) + { + m_dist -= m_dx; + m_dist_start -= m_dx_start; + } + if(dy < 0) + { + m_dist += m_dx; + m_dist_start += m_dx_start; + } + } + + //--------------------------------------------------------------------- + void inc_y(int dx) + { + m_dist -= m_dx; + m_dist_start -= m_dx_start; + if(dx > 0) + { + m_dist += m_dy; + m_dist_start += m_dy_start; + } + if(dx < 0) + { + m_dist -= m_dy; + m_dist_start -= m_dy_start; + } + } + + //--------------------------------------------------------------------- + void dec_y(int dx) + { + m_dist += m_dx; + m_dist_start += m_dx_start; + if(dx > 0) + { + m_dist += m_dy; + m_dist_start += m_dy_start; + } + if(dx < 0) + { + m_dist -= m_dy; + m_dist_start -= m_dy_start; + } + } + + //--------------------------------------------------------------------- + int dist() const { return m_dist; } + int dist_start() const { return m_dist_start; } + int dist_end() const { return m_dist_start; } + + //--------------------------------------------------------------------- + int dx() const { return m_dx; } + int dy() const { return m_dy; } + int dx_start() const { return m_dx_start; } + int dy_start() const { return m_dy_start; } + int dx_end() const { return m_dx_start; } + int dy_end() const { return m_dy_start; } + + private: + //--------------------------------------------------------------------- + int m_dx; + int m_dy; + int m_dx_start; + int m_dy_start; + + int m_dist; + int m_dist_start; + }; + + + + + + //===================================================distance_interpolator3 + class distance_interpolator3 + { + public: + //--------------------------------------------------------------------- + distance_interpolator3() {} + distance_interpolator3(int x1, int y1, int x2, int y2, + int sx, int sy, int ex, int ey, + int x, int y) : + m_dx(x2 - x1), + m_dy(y2 - y1), + m_dx_start(line_mr(sx) - line_mr(x1)), + m_dy_start(line_mr(sy) - line_mr(y1)), + m_dx_end(line_mr(ex) - line_mr(x2)), + m_dy_end(line_mr(ey) - line_mr(y2)), + + m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) - + double(y + line_subpixel_scale/2 - y2) * double(m_dx))), + + m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start - + (line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start), + + m_dist_end((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_end - + (line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_end) + { + m_dx <<= line_subpixel_shift; + m_dy <<= line_subpixel_shift; + m_dx_start <<= line_mr_subpixel_shift; + m_dy_start <<= line_mr_subpixel_shift; + m_dx_end <<= line_mr_subpixel_shift; + m_dy_end <<= line_mr_subpixel_shift; + } + + //--------------------------------------------------------------------- + void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; } + void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; } + void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; } + void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; } + + //--------------------------------------------------------------------- + void inc_x(int dy) + { + m_dist += m_dy; + m_dist_start += m_dy_start; + m_dist_end += m_dy_end; + if(dy > 0) + { + m_dist -= m_dx; + m_dist_start -= m_dx_start; + m_dist_end -= m_dx_end; + } + if(dy < 0) + { + m_dist += m_dx; + m_dist_start += m_dx_start; + m_dist_end += m_dx_end; + } + } + + //--------------------------------------------------------------------- + void dec_x(int dy) + { + m_dist -= m_dy; + m_dist_start -= m_dy_start; + m_dist_end -= m_dy_end; + if(dy > 0) + { + m_dist -= m_dx; + m_dist_start -= m_dx_start; + m_dist_end -= m_dx_end; + } + if(dy < 0) + { + m_dist += m_dx; + m_dist_start += m_dx_start; + m_dist_end += m_dx_end; + } + } + + //--------------------------------------------------------------------- + void inc_y(int dx) + { + m_dist -= m_dx; + m_dist_start -= m_dx_start; + m_dist_end -= m_dx_end; + if(dx > 0) + { + m_dist += m_dy; + m_dist_start += m_dy_start; + m_dist_end += m_dy_end; + } + if(dx < 0) + { + m_dist -= m_dy; + m_dist_start -= m_dy_start; + m_dist_end -= m_dy_end; + } + } + + //--------------------------------------------------------------------- + void dec_y(int dx) + { + m_dist += m_dx; + m_dist_start += m_dx_start; + m_dist_end += m_dx_end; + if(dx > 0) + { + m_dist += m_dy; + m_dist_start += m_dy_start; + m_dist_end += m_dy_end; + } + if(dx < 0) + { + m_dist -= m_dy; + m_dist_start -= m_dy_start; + m_dist_end -= m_dy_end; + } + } + + //--------------------------------------------------------------------- + int dist() const { return m_dist; } + int dist_start() const { return m_dist_start; } + int dist_end() const { return m_dist_end; } + + //--------------------------------------------------------------------- + int dx() const { return m_dx; } + int dy() const { return m_dy; } + int dx_start() const { return m_dx_start; } + int dy_start() const { return m_dy_start; } + int dx_end() const { return m_dx_end; } + int dy_end() const { return m_dy_end; } + + private: + //--------------------------------------------------------------------- + int m_dx; + int m_dy; + int m_dx_start; + int m_dy_start; + int m_dx_end; + int m_dy_end; + + int m_dist; + int m_dist_start; + int m_dist_end; + }; + + + + + + //================================================line_interpolator_aa_base + template<class Renderer> class line_interpolator_aa_base + { + public: + typedef Renderer renderer_type; + typedef typename Renderer::color_type color_type; + + //--------------------------------------------------------------------- + enum max_half_width_e + { + max_half_width = 64 + }; + + //--------------------------------------------------------------------- + line_interpolator_aa_base(renderer_type& ren, line_parameters& lp) : + m_lp(&lp), + m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) : + line_dbl_hr(lp.y2 - lp.y1), + lp.vertical ? std::abs(lp.y2 - lp.y1) : + std::abs(lp.x2 - lp.x1) + 1), + m_ren(ren), + m_len((lp.vertical == (lp.inc > 0)) ? -lp.len : lp.len), + m_x(lp.x1 >> line_subpixel_shift), + m_y(lp.y1 >> line_subpixel_shift), + m_old_x(m_x), + m_old_y(m_y), + m_count((lp.vertical ? std::abs((lp.y2 >> line_subpixel_shift) - m_y) : + std::abs((lp.x2 >> line_subpixel_shift) - m_x))), + m_width(ren.subpixel_width()), + //m_max_extent(m_width >> (line_subpixel_shift - 2)), + m_max_extent((m_width + line_subpixel_mask) >> line_subpixel_shift), + m_step(0) + { + agg::dda2_line_interpolator li(0, lp.vertical ? + (lp.dy << agg::line_subpixel_shift) : + (lp.dx << agg::line_subpixel_shift), + lp.len); + + unsigned i; + int stop = m_width + line_subpixel_scale * 2; + for(i = 0; i < max_half_width; ++i) + { + m_dist[i] = li.y(); + if(m_dist[i] >= stop) break; + ++li; + } + m_dist[i++] = 0x7FFF0000; + } + + //--------------------------------------------------------------------- + template<class DI> int step_hor_base(DI& di) + { + ++m_li; + m_x += m_lp->inc; + m_y = (m_lp->y1 + m_li.y()) >> line_subpixel_shift; + + if(m_lp->inc > 0) di.inc_x(m_y - m_old_y); + else di.dec_x(m_y - m_old_y); + + m_old_y = m_y; + + return di.dist() / m_len; + } + + //--------------------------------------------------------------------- + template<class DI> int step_ver_base(DI& di) + { + ++m_li; + m_y += m_lp->inc; + m_x = (m_lp->x1 + m_li.y()) >> line_subpixel_shift; + + if(m_lp->inc > 0) di.inc_y(m_x - m_old_x); + else di.dec_y(m_x - m_old_x); + + m_old_x = m_x; + + return di.dist() / m_len; + } + + //--------------------------------------------------------------------- + bool vertical() const { return m_lp->vertical; } + int width() const { return m_width; } + int count() const { return m_count; } + + private: + line_interpolator_aa_base(const line_interpolator_aa_base<Renderer>&); + const line_interpolator_aa_base<Renderer>& + operator = (const line_interpolator_aa_base<Renderer>&); + + protected: + line_parameters* m_lp; + dda2_line_interpolator m_li; + renderer_type& m_ren; + int m_len; + int m_x; + int m_y; + int m_old_x; + int m_old_y; + int m_count; + int m_width; + int m_max_extent; + int m_step; + int m_dist[max_half_width + 1]; + cover_type m_covers[max_half_width * 2 + 4]; + }; + + + + + + + + //====================================================line_interpolator_aa0 + template<class Renderer> class line_interpolator_aa0 : + public line_interpolator_aa_base<Renderer> + { + public: + typedef Renderer renderer_type; + typedef typename Renderer::color_type color_type; + typedef line_interpolator_aa_base<Renderer> base_type; + + //--------------------------------------------------------------------- + line_interpolator_aa0(renderer_type& ren, line_parameters& lp) : + line_interpolator_aa_base<Renderer>(ren, lp), + m_di(lp.x1, lp.y1, lp.x2, lp.y2, + lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) + { + base_type::m_li.adjust_forward(); + } + + //--------------------------------------------------------------------- + bool step_hor() + { + int dist; + int dy; + int s1 = base_type::step_hor_base(m_di); + cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; + cover_type* p1 = p0; + + *p1++ = (cover_type)base_type::m_ren.cover(s1); + + dy = 1; + while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) + { + *p1++ = (cover_type)base_type::m_ren.cover(dist); + ++dy; + } + + dy = 1; + while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) + { + *--p0 = (cover_type)base_type::m_ren.cover(dist); + ++dy; + } + base_type::m_ren.blend_solid_vspan(base_type::m_x, + base_type::m_y - dy + 1, + unsigned(p1 - p0), + p0); + return ++base_type::m_step < base_type::m_count; + } + + //--------------------------------------------------------------------- + bool step_ver() + { + int dist; + int dx; + int s1 = base_type::step_ver_base(m_di); + cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; + cover_type* p1 = p0; + + *p1++ = (cover_type)base_type::m_ren.cover(s1); + + dx = 1; + while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) + { + *p1++ = (cover_type)base_type::m_ren.cover(dist); + ++dx; + } + + dx = 1; + while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) + { + *--p0 = (cover_type)base_type::m_ren.cover(dist); + ++dx; + } + base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, + base_type::m_y, + unsigned(p1 - p0), + p0); + return ++base_type::m_step < base_type::m_count; + } + + private: + line_interpolator_aa0(const line_interpolator_aa0<Renderer>&); + const line_interpolator_aa0<Renderer>& + operator = (const line_interpolator_aa0<Renderer>&); + + //--------------------------------------------------------------------- + distance_interpolator1 m_di; + }; + + + + + + + //====================================================line_interpolator_aa1 + template<class Renderer> class line_interpolator_aa1 : + public line_interpolator_aa_base<Renderer> + { + public: + typedef Renderer renderer_type; + typedef typename Renderer::color_type color_type; + typedef line_interpolator_aa_base<Renderer> base_type; + + //--------------------------------------------------------------------- + line_interpolator_aa1(renderer_type& ren, line_parameters& lp, + int sx, int sy) : + line_interpolator_aa_base<Renderer>(ren, lp), + m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, + lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) + { + int dist1_start; + int dist2_start; + + int npix = 1; + + if(lp.vertical) + { + do + { + --base_type::m_li; + base_type::m_y -= lp.inc; + base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift; + + if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x); + else m_di.inc_y(base_type::m_x - base_type::m_old_x); + + base_type::m_old_x = base_type::m_x; + + dist1_start = dist2_start = m_di.dist_start(); + + int dx = 0; + if(dist1_start < 0) ++npix; + do + { + dist1_start += m_di.dy_start(); + dist2_start -= m_di.dy_start(); + if(dist1_start < 0) ++npix; + if(dist2_start < 0) ++npix; + ++dx; + } + while(base_type::m_dist[dx] <= base_type::m_width); + --base_type::m_step; + if(npix == 0) break; + npix = 0; + } + while(base_type::m_step >= -base_type::m_max_extent); + } + else + { + do + { + --base_type::m_li; + base_type::m_x -= lp.inc; + base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift; + + if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y); + else m_di.inc_x(base_type::m_y - base_type::m_old_y); + + base_type::m_old_y = base_type::m_y; + + dist1_start = dist2_start = m_di.dist_start(); + + int dy = 0; + if(dist1_start < 0) ++npix; + do + { + dist1_start -= m_di.dx_start(); + dist2_start += m_di.dx_start(); + if(dist1_start < 0) ++npix; + if(dist2_start < 0) ++npix; + ++dy; + } + while(base_type::m_dist[dy] <= base_type::m_width); + --base_type::m_step; + if(npix == 0) break; + npix = 0; + } + while(base_type::m_step >= -base_type::m_max_extent); + } + base_type::m_li.adjust_forward(); + } + + //--------------------------------------------------------------------- + bool step_hor() + { + int dist_start; + int dist; + int dy; + int s1 = base_type::step_hor_base(m_di); + + dist_start = m_di.dist_start(); + cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; + cover_type* p1 = p0; + + *p1 = 0; + if(dist_start <= 0) + { + *p1 = (cover_type)base_type::m_ren.cover(s1); + } + ++p1; + + dy = 1; + while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) + { + dist_start -= m_di.dx_start(); + *p1 = 0; + if(dist_start <= 0) + { + *p1 = (cover_type)base_type::m_ren.cover(dist); + } + ++p1; + ++dy; + } + + dy = 1; + dist_start = m_di.dist_start(); + while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) + { + dist_start += m_di.dx_start(); + *--p0 = 0; + if(dist_start <= 0) + { + *p0 = (cover_type)base_type::m_ren.cover(dist); + } + ++dy; + } + + base_type::m_ren.blend_solid_vspan(base_type::m_x, + base_type::m_y - dy + 1, + unsigned(p1 - p0), + p0); + return ++base_type::m_step < base_type::m_count; + } + + //--------------------------------------------------------------------- + bool step_ver() + { + int dist_start; + int dist; + int dx; + int s1 = base_type::step_ver_base(m_di); + cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; + cover_type* p1 = p0; + + dist_start = m_di.dist_start(); + + *p1 = 0; + if(dist_start <= 0) + { + *p1 = (cover_type)base_type::m_ren.cover(s1); + } + ++p1; + + dx = 1; + while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) + { + dist_start += m_di.dy_start(); + *p1 = 0; + if(dist_start <= 0) + { + *p1 = (cover_type)base_type::m_ren.cover(dist); + } + ++p1; + ++dx; + } + + dx = 1; + dist_start = m_di.dist_start(); + while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) + { + dist_start -= m_di.dy_start(); + *--p0 = 0; + if(dist_start <= 0) + { + *p0 = (cover_type)base_type::m_ren.cover(dist); + } + ++dx; + } + base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, + base_type::m_y, + unsigned(p1 - p0), + p0); + return ++base_type::m_step < base_type::m_count; + } + + private: + line_interpolator_aa1(const line_interpolator_aa1<Renderer>&); + const line_interpolator_aa1<Renderer>& + operator = (const line_interpolator_aa1<Renderer>&); + + //--------------------------------------------------------------------- + distance_interpolator2 m_di; + }; + + + + + + + + + + + + + //====================================================line_interpolator_aa2 + template<class Renderer> class line_interpolator_aa2 : + public line_interpolator_aa_base<Renderer> + { + public: + typedef Renderer renderer_type; + typedef typename Renderer::color_type color_type; + typedef line_interpolator_aa_base<Renderer> base_type; + + //--------------------------------------------------------------------- + line_interpolator_aa2(renderer_type& ren, line_parameters& lp, + int ex, int ey) : + line_interpolator_aa_base<Renderer>(ren, lp), + m_di(lp.x1, lp.y1, lp.x2, lp.y2, ex, ey, + lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask, + 0) + { + base_type::m_li.adjust_forward(); + base_type::m_step -= base_type::m_max_extent; + } + + //--------------------------------------------------------------------- + bool step_hor() + { + int dist_end; + int dist; + int dy; + int s1 = base_type::step_hor_base(m_di); + cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; + cover_type* p1 = p0; + + dist_end = m_di.dist_end(); + + int npix = 0; + *p1 = 0; + if(dist_end > 0) + { + *p1 = (cover_type)base_type::m_ren.cover(s1); + ++npix; + } + ++p1; + + dy = 1; + while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) + { + dist_end -= m_di.dx_end(); + *p1 = 0; + if(dist_end > 0) + { + *p1 = (cover_type)base_type::m_ren.cover(dist); + ++npix; + } + ++p1; + ++dy; + } + + dy = 1; + dist_end = m_di.dist_end(); + while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) + { + dist_end += m_di.dx_end(); + *--p0 = 0; + if(dist_end > 0) + { + *p0 = (cover_type)base_type::m_ren.cover(dist); + ++npix; + } + ++dy; + } + base_type::m_ren.blend_solid_vspan(base_type::m_x, + base_type::m_y - dy + 1, + unsigned(p1 - p0), + p0); + return npix && ++base_type::m_step < base_type::m_count; + } + + //--------------------------------------------------------------------- + bool step_ver() + { + int dist_end; + int dist; + int dx; + int s1 = base_type::step_ver_base(m_di); + cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; + cover_type* p1 = p0; + + dist_end = m_di.dist_end(); + + int npix = 0; + *p1 = 0; + if(dist_end > 0) + { + *p1 = (cover_type)base_type::m_ren.cover(s1); + ++npix; + } + ++p1; + + dx = 1; + while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) + { + dist_end += m_di.dy_end(); + *p1 = 0; + if(dist_end > 0) + { + *p1 = (cover_type)base_type::m_ren.cover(dist); + ++npix; + } + ++p1; + ++dx; + } + + dx = 1; + dist_end = m_di.dist_end(); + while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) + { + dist_end -= m_di.dy_end(); + *--p0 = 0; + if(dist_end > 0) + { + *p0 = (cover_type)base_type::m_ren.cover(dist); + ++npix; + } + ++dx; + } + base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, + base_type::m_y, + unsigned(p1 - p0), + p0); + return npix && ++base_type::m_step < base_type::m_count; + } + + private: + line_interpolator_aa2(const line_interpolator_aa2<Renderer>&); + const line_interpolator_aa2<Renderer>& + operator = (const line_interpolator_aa2<Renderer>&); + + //--------------------------------------------------------------------- + distance_interpolator2 m_di; + }; + + + + + + + + + + + //====================================================line_interpolator_aa3 + template<class Renderer> class line_interpolator_aa3 : + public line_interpolator_aa_base<Renderer> + { + public: + typedef Renderer renderer_type; + typedef typename Renderer::color_type color_type; + typedef line_interpolator_aa_base<Renderer> base_type; + + //--------------------------------------------------------------------- + line_interpolator_aa3(renderer_type& ren, line_parameters& lp, + int sx, int sy, int ex, int ey) : + line_interpolator_aa_base<Renderer>(ren, lp), + m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, + lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask) + { + int dist1_start; + int dist2_start; + int npix = 1; + if(lp.vertical) + { + do + { + --base_type::m_li; + base_type::m_y -= lp.inc; + base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift; + + if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x); + else m_di.inc_y(base_type::m_x - base_type::m_old_x); + + base_type::m_old_x = base_type::m_x; + + dist1_start = dist2_start = m_di.dist_start(); + + int dx = 0; + if(dist1_start < 0) ++npix; + do + { + dist1_start += m_di.dy_start(); + dist2_start -= m_di.dy_start(); + if(dist1_start < 0) ++npix; + if(dist2_start < 0) ++npix; + ++dx; + } + while(base_type::m_dist[dx] <= base_type::m_width); + if(npix == 0) break; + npix = 0; + } + while(--base_type::m_step >= -base_type::m_max_extent); + } + else + { + do + { + --base_type::m_li; + base_type::m_x -= lp.inc; + base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift; + + if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y); + else m_di.inc_x(base_type::m_y - base_type::m_old_y); + + base_type::m_old_y = base_type::m_y; + + dist1_start = dist2_start = m_di.dist_start(); + + int dy = 0; + if(dist1_start < 0) ++npix; + do + { + dist1_start -= m_di.dx_start(); + dist2_start += m_di.dx_start(); + if(dist1_start < 0) ++npix; + if(dist2_start < 0) ++npix; + ++dy; + } + while(base_type::m_dist[dy] <= base_type::m_width); + if(npix == 0) break; + npix = 0; + } + while(--base_type::m_step >= -base_type::m_max_extent); + } + base_type::m_li.adjust_forward(); + base_type::m_step -= base_type::m_max_extent; + } + + + //--------------------------------------------------------------------- + bool step_hor() + { + int dist_start; + int dist_end; + int dist; + int dy; + int s1 = base_type::step_hor_base(m_di); + cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; + cover_type* p1 = p0; + + dist_start = m_di.dist_start(); + dist_end = m_di.dist_end(); + + int npix = 0; + *p1 = 0; + if(dist_end > 0) + { + if(dist_start <= 0) + { + *p1 = (cover_type)base_type::m_ren.cover(s1); + } + ++npix; + } + ++p1; + + dy = 1; + while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width) + { + dist_start -= m_di.dx_start(); + dist_end -= m_di.dx_end(); + *p1 = 0; + if(dist_end > 0 && dist_start <= 0) + { + *p1 = (cover_type)base_type::m_ren.cover(dist); + ++npix; + } + ++p1; + ++dy; + } + + dy = 1; + dist_start = m_di.dist_start(); + dist_end = m_di.dist_end(); + while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width) + { + dist_start += m_di.dx_start(); + dist_end += m_di.dx_end(); + *--p0 = 0; + if(dist_end > 0 && dist_start <= 0) + { + *p0 = (cover_type)base_type::m_ren.cover(dist); + ++npix; + } + ++dy; + } + base_type::m_ren.blend_solid_vspan(base_type::m_x, + base_type::m_y - dy + 1, + unsigned(p1 - p0), + p0); + return npix && ++base_type::m_step < base_type::m_count; + } + + //--------------------------------------------------------------------- + bool step_ver() + { + int dist_start; + int dist_end; + int dist; + int dx; + int s1 = base_type::step_ver_base(m_di); + cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2; + cover_type* p1 = p0; + + dist_start = m_di.dist_start(); + dist_end = m_di.dist_end(); + + int npix = 0; + *p1 = 0; + if(dist_end > 0) + { + if(dist_start <= 0) + { + *p1 = (cover_type)base_type::m_ren.cover(s1); + } + ++npix; + } + ++p1; + + dx = 1; + while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width) + { + dist_start += m_di.dy_start(); + dist_end += m_di.dy_end(); + *p1 = 0; + if(dist_end > 0 && dist_start <= 0) + { + *p1 = (cover_type)base_type::m_ren.cover(dist); + ++npix; + } + ++p1; + ++dx; + } + + dx = 1; + dist_start = m_di.dist_start(); + dist_end = m_di.dist_end(); + while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width) + { + dist_start -= m_di.dy_start(); + dist_end -= m_di.dy_end(); + *--p0 = 0; + if(dist_end > 0 && dist_start <= 0) + { + *p0 = (cover_type)base_type::m_ren.cover(dist); + ++npix; + } + ++dx; + } + base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1, + base_type::m_y, + unsigned(p1 - p0), + p0); + return npix && ++base_type::m_step < base_type::m_count; + } + + private: + line_interpolator_aa3(const line_interpolator_aa3<Renderer>&); + const line_interpolator_aa3<Renderer>& + operator = (const line_interpolator_aa3<Renderer>&); + + //--------------------------------------------------------------------- + distance_interpolator3 m_di; + }; + + + + + //==========================================================line_profile_aa + // + // See Implementation agg_line_profile_aa.cpp + // + class line_profile_aa + { + public: + //--------------------------------------------------------------------- + typedef int8u value_type; + enum subpixel_scale_e + { + subpixel_shift = line_subpixel_shift, + subpixel_scale = 1 << subpixel_shift, + subpixel_mask = subpixel_scale - 1 + }; + + enum aa_scale_e + { + aa_shift = 8, + aa_scale = 1 << aa_shift, + aa_mask = aa_scale - 1 + }; + + //--------------------------------------------------------------------- + line_profile_aa() : + m_subpixel_width(0), + m_min_width(1.0), + m_smoother_width(1.0) + { + int i; + for(i = 0; i < aa_scale; i++) m_gamma[i] = (value_type)i; + } + + //--------------------------------------------------------------------- + template<class GammaF> + line_profile_aa(double w, const GammaF& gamma_function) : + m_subpixel_width(0), + m_min_width(1.0), + m_smoother_width(1.0) + { + gamma(gamma_function); + width(w); + } + + //--------------------------------------------------------------------- + void min_width(double w) { m_min_width = w; } + void smoother_width(double w) { m_smoother_width = w; } + + //--------------------------------------------------------------------- + template<class GammaF> void gamma(const GammaF& gamma_function) + { + int i; + for(i = 0; i < aa_scale; i++) + { + m_gamma[i] = value_type( + uround(gamma_function(double(i) / aa_mask) * aa_mask)); + } + } + + void width(double w); + + unsigned profile_size() const { return m_profile.size(); } + int subpixel_width() const { return m_subpixel_width; } + + //--------------------------------------------------------------------- + double min_width() const { return m_min_width; } + double smoother_width() const { return m_smoother_width; } + + //--------------------------------------------------------------------- + value_type value(int dist) const + { + return m_profile[dist + subpixel_scale*2]; + } + + private: + line_profile_aa(const line_profile_aa&); + const line_profile_aa& operator = (const line_profile_aa&); + + value_type* profile(double w); + void set(double center_width, double smoother_width); + + //--------------------------------------------------------------------- + pod_array<value_type> m_profile; + value_type m_gamma[aa_scale]; + int m_subpixel_width; + double m_min_width; + double m_smoother_width; + }; + + + //======================================================renderer_outline_aa + template<class BaseRenderer> class renderer_outline_aa + { + public: + //--------------------------------------------------------------------- + typedef BaseRenderer base_ren_type; + typedef renderer_outline_aa<base_ren_type> self_type; + typedef typename base_ren_type::color_type color_type; + + //--------------------------------------------------------------------- + renderer_outline_aa(base_ren_type& ren, line_profile_aa& prof) : + m_ren(&ren), + m_profile(&prof), + m_clip_box(0,0,0,0), + m_clipping(false) + {} + void attach(base_ren_type& ren) { m_ren = &ren; } + + //--------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + + //--------------------------------------------------------------------- + void profile(line_profile_aa& prof) { m_profile = &prof; } + const line_profile_aa& profile() const { return *m_profile; } + line_profile_aa& profile() { return *m_profile; } + + //--------------------------------------------------------------------- + int subpixel_width() const { return m_profile->subpixel_width(); } + + //--------------------------------------------------------------------- + void reset_clipping() { m_clipping = false; } + void clip_box(double x1, double y1, double x2, double y2) + { + m_clip_box.x1 = line_coord_sat::conv(x1); + m_clip_box.y1 = line_coord_sat::conv(y1); + m_clip_box.x2 = line_coord_sat::conv(x2); + m_clip_box.y2 = line_coord_sat::conv(y2); + m_clipping = true; + } + + //--------------------------------------------------------------------- + int cover(int d) const + { + return m_profile->value(d); + } + + //------------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, unsigned len, const cover_type* covers) + { + m_ren->blend_solid_hspan(x, y, len, m_color, covers); + } + + //------------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, unsigned len, const cover_type* covers) + { + m_ren->blend_solid_vspan(x, y, len, m_color, covers); + } + + //------------------------------------------------------------------------- + static bool accurate_join_only() { return false; } + + //------------------------------------------------------------------------- + template<class Cmp> + void semidot_hline(Cmp cmp, + int xc1, int yc1, int xc2, int yc2, + int x1, int y1, int x2) + { + cover_type covers[line_interpolator_aa_base<self_type>::max_half_width * 2 + 4]; + cover_type* p0 = covers; + cover_type* p1 = covers; + int x = x1 << line_subpixel_shift; + int y = y1 << line_subpixel_shift; + int w = subpixel_width(); + distance_interpolator0 di(xc1, yc1, xc2, yc2, x, y); + x += line_subpixel_scale/2; + y += line_subpixel_scale/2; + + int x0 = x1; + int dx = x - xc1; + int dy = y - yc1; + do + { + int d = int(fast_sqrt(dx*dx + dy*dy)); + *p1 = 0; + if(cmp(di.dist()) && d <= w) + { + *p1 = (cover_type)cover(d); + } + ++p1; + dx += line_subpixel_scale; + di.inc_x(); + } + while(++x1 <= x2); + m_ren->blend_solid_hspan(x0, y1, + unsigned(p1 - p0), + color(), + p0); + } + + //------------------------------------------------------------------------- + template<class Cmp> + void semidot(Cmp cmp, int xc1, int yc1, int xc2, int yc2) + { + if(m_clipping && clipping_flags(xc1, yc1, m_clip_box)) return; + + int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift); + if(r < 1) r = 1; + ellipse_bresenham_interpolator ei(r, r); + int dx = 0; + int dy = -r; + int dy0 = dy; + int dx0 = dx; + int x = xc1 >> line_subpixel_shift; + int y = yc1 >> line_subpixel_shift; + + do + { + dx += ei.dx(); + dy += ei.dy(); + + if(dy != dy0) + { + semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0); + semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y-dy0, x+dx0); + } + dx0 = dx; + dy0 = dy; + ++ei; + } + while(dy < 0); + semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0); + } + + //------------------------------------------------------------------------- + void pie_hline(int xc, int yc, int xp1, int yp1, int xp2, int yp2, + int xh1, int yh1, int xh2) + { + if(m_clipping && clipping_flags(xc, yc, m_clip_box)) return; + + cover_type covers[line_interpolator_aa_base<self_type>::max_half_width * 2 + 4]; + cover_type* p0 = covers; + cover_type* p1 = covers; + int x = xh1 << line_subpixel_shift; + int y = yh1 << line_subpixel_shift; + int w = subpixel_width(); + + distance_interpolator00 di(xc, yc, xp1, yp1, xp2, yp2, x, y); + x += line_subpixel_scale/2; + y += line_subpixel_scale/2; + + int xh0 = xh1; + int dx = x - xc; + int dy = y - yc; + do + { + int d = int(fast_sqrt(dx*dx + dy*dy)); + *p1 = 0; + if(di.dist1() <= 0 && di.dist2() > 0 && d <= w) + { + *p1 = (cover_type)cover(d); + } + ++p1; + dx += line_subpixel_scale; + di.inc_x(); + } + while(++xh1 <= xh2); + m_ren->blend_solid_hspan(xh0, yh1, + unsigned(p1 - p0), + color(), + p0); + } + + + //------------------------------------------------------------------------- + void pie(int xc, int yc, int x1, int y1, int x2, int y2) + { + int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift); + if(r < 1) r = 1; + ellipse_bresenham_interpolator ei(r, r); + int dx = 0; + int dy = -r; + int dy0 = dy; + int dx0 = dx; + int x = xc >> line_subpixel_shift; + int y = yc >> line_subpixel_shift; + + do + { + dx += ei.dx(); + dy += ei.dy(); + + if(dy != dy0) + { + pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y+dy0, x+dx0); + pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y-dy0, x+dx0); + } + dx0 = dx; + dy0 = dy; + ++ei; + } + while(dy < 0); + pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y+dy0, x+dx0); + } + + //------------------------------------------------------------------------- + void line0_no_clip(line_parameters& lp) + { + if(lp.len > line_max_length) + { + line_parameters lp1, lp2; + lp.divide(lp1, lp2); + line0_no_clip(lp1); + line0_no_clip(lp2); + return; + } + + line_interpolator_aa0<self_type> li(*this, lp); + if(li.count()) + { + if(li.vertical()) + { + while(li.step_ver()); + } + else + { + while(li.step_hor()); + } + } + } + + //------------------------------------------------------------------------- + void line0(line_parameters& lp) + { + if(m_clipping) + { + int x1 = lp.x1; + int y1 = lp.y1; + int x2 = lp.x2; + int y2 = lp.y2; + unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box); + if((flags & 4) == 0) + { + if(flags) + { + line_parameters lp2(x1, y1, x2, y2, + uround(calc_distance(x1, y1, x2, y2))); + line0_no_clip(lp2); + } + else + { + line0_no_clip(lp); + } + } + } + else + { + line0_no_clip(lp); + } + } + + //------------------------------------------------------------------------- + void line1_no_clip(line_parameters& lp, int sx, int sy) + { + if(lp.len > line_max_length) + { + line_parameters lp1, lp2; + lp.divide(lp1, lp2); + line1_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1); + line1_no_clip(lp2, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1)); + return; + } + + fix_degenerate_bisectrix_start(lp, &sx, &sy); + line_interpolator_aa1<self_type> li(*this, lp, sx, sy); + if(li.vertical()) + { + while(li.step_ver()); + } + else + { + while(li.step_hor()); + } + } + + + //------------------------------------------------------------------------- + void line1(line_parameters& lp, int sx, int sy) + { + if(m_clipping) + { + int x1 = lp.x1; + int y1 = lp.y1; + int x2 = lp.x2; + int y2 = lp.y2; + unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box); + if((flags & 4) == 0) + { + if(flags) + { + line_parameters lp2(x1, y1, x2, y2, + uround(calc_distance(x1, y1, x2, y2))); + if(flags & 1) + { + sx = x1 + (y2 - y1); + sy = y1 - (x2 - x1); + } + else + { + while(std::abs(sx - lp.x1) + std::abs(sy - lp.y1) > lp2.len) + { + sx = (lp.x1 + sx) >> 1; + sy = (lp.y1 + sy) >> 1; + } + } + line1_no_clip(lp2, sx, sy); + } + else + { + line1_no_clip(lp, sx, sy); + } + } + } + else + { + line1_no_clip(lp, sx, sy); + } + } + + //------------------------------------------------------------------------- + void line2_no_clip(line_parameters& lp, int ex, int ey) + { + if(lp.len > line_max_length) + { + line_parameters lp1, lp2; + lp.divide(lp1, lp2); + line2_no_clip(lp1, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1)); + line2_no_clip(lp2, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1); + return; + } + + fix_degenerate_bisectrix_end(lp, &ex, &ey); + line_interpolator_aa2<self_type> li(*this, lp, ex, ey); + if(li.vertical()) + { + while(li.step_ver()); + } + else + { + while(li.step_hor()); + } + } + + //------------------------------------------------------------------------- + void line2(line_parameters& lp, int ex, int ey) + { + if(m_clipping) + { + int x1 = lp.x1; + int y1 = lp.y1; + int x2 = lp.x2; + int y2 = lp.y2; + unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box); + if((flags & 4) == 0) + { + if(flags) + { + line_parameters lp2(x1, y1, x2, y2, + uround(calc_distance(x1, y1, x2, y2))); + if(flags & 2) + { + ex = x2 + (y2 - y1); + ey = y2 - (x2 - x1); + } + else + { + while(std::abs(ex - lp.x2) + std::abs(ey - lp.y2) > lp2.len) + { + ex = (lp.x2 + ex) >> 1; + ey = (lp.y2 + ey) >> 1; + } + } + line2_no_clip(lp2, ex, ey); + } + else + { + line2_no_clip(lp, ex, ey); + } + } + } + else + { + line2_no_clip(lp, ex, ey); + } + } + + //------------------------------------------------------------------------- + void line3_no_clip(line_parameters& lp, + int sx, int sy, int ex, int ey) + { + if(lp.len > line_max_length) + { + line_parameters lp1, lp2; + lp.divide(lp1, lp2); + int mx = lp1.x2 + (lp1.y2 - lp1.y1); + int my = lp1.y2 - (lp1.x2 - lp1.x1); + line3_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1, mx, my); + line3_no_clip(lp2, mx, my, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1); + return; + } + + fix_degenerate_bisectrix_start(lp, &sx, &sy); + fix_degenerate_bisectrix_end(lp, &ex, &ey); + line_interpolator_aa3<self_type> li(*this, lp, sx, sy, ex, ey); + if(li.vertical()) + { + while(li.step_ver()); + } + else + { + while(li.step_hor()); + } + } + + //------------------------------------------------------------------------- + void line3(line_parameters& lp, + int sx, int sy, int ex, int ey) + { + if(m_clipping) + { + int x1 = lp.x1; + int y1 = lp.y1; + int x2 = lp.x2; + int y2 = lp.y2; + unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box); + if((flags & 4) == 0) + { + if(flags) + { + line_parameters lp2(x1, y1, x2, y2, + uround(calc_distance(x1, y1, x2, y2))); + if(flags & 1) + { + sx = x1 + (y2 - y1); + sy = y1 - (x2 - x1); + } + else + { + while(std::abs(sx - lp.x1) + std::abs(sy - lp.y1) > lp2.len) + { + sx = (lp.x1 + sx) >> 1; + sy = (lp.y1 + sy) >> 1; + } + } + if(flags & 2) + { + ex = x2 + (y2 - y1); + ey = y2 - (x2 - x1); + } + else + { + while(std::abs(ex - lp.x2) + std::abs(ey - lp.y2) > lp2.len) + { + ex = (lp.x2 + ex) >> 1; + ey = (lp.y2 + ey) >> 1; + } + } + line3_no_clip(lp2, sx, sy, ex, ey); + } + else + { + line3_no_clip(lp, sx, sy, ex, ey); + } + } + } + else + { + line3_no_clip(lp, sx, sy, ex, ey); + } + } + + + private: + base_ren_type* m_ren; + line_profile_aa* m_profile; + color_type m_color; + rect_i m_clip_box; + bool m_clipping; + }; + + + +} + +#endif diff --git a/include/agg_renderer_outline_image.h b/include/agg_renderer_outline_image.h new file mode 100644 index 0000000..7ecded5 --- /dev/null +++ b/include/agg_renderer_outline_image.h @@ -0,0 +1,1037 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_RENDERER_OUTLINE_IMAGE_INCLUDED +#define AGG_RENDERER_OUTLINE_IMAGE_INCLUDED + +#include <cstdlib> +#include "agg_array.h" +#include "agg_math.h" +#include "agg_line_aa_basics.h" +#include "agg_dda_line.h" +#include "agg_rendering_buffer.h" +#include "agg_clip_liang_barsky.h" + + +namespace agg +{ + //========================================================line_image_scale + template<class Source> class line_image_scale + { + public: + typedef typename Source::color_type color_type; + + line_image_scale(const Source& src, double height) : + m_source(src), + m_height(height), + m_scale(src.height() / height), + m_scale_inv(height / src.height()) + { + } + + double width() const { return m_source.width(); } + double height() const { return m_height; } + + color_type pixel(int x, int y) const + { + if (m_scale < 1.0) + { + // Interpolate between nearest source pixels. + double src_y = (y + 0.5) * m_scale - 0.5; + int h = m_source.height() - 1; + int y1 = ifloor(src_y); + int y2 = y1 + 1; + rgba pix1 = (y1 < 0) ? rgba::no_color() : rgba(m_source.pixel(x, y1)); + rgba pix2 = (y2 > h) ? rgba::no_color() : rgba(m_source.pixel(x, y2)); + return pix1.gradient(pix2, src_y - y1); + } + else + { + // Average source pixels between y and y+1. + double src_y1 = (y + 0.5) * m_scale - 0.5; + double src_y2 = src_y1 + m_scale; + int h = m_source.height() - 1; + int y1 = ifloor(src_y1); + int y2 = ifloor(src_y2); + rgba c = rgba::no_color(); + if (y1 >= 0) c += rgba(m_source.pixel(x, y1)) *= y1 + 1 - src_y1; + while (++y1 < y2) + { + if (y1 <= h) c += m_source.pixel(x, y1); + } + if (y2 <= h) c += rgba(m_source.pixel(x, y2)) *= src_y2 - y2; + return c *= m_scale_inv; + } + } + + private: + line_image_scale(const line_image_scale<Source>&); + const line_image_scale<Source>& operator = (const line_image_scale<Source>&); + + const Source& m_source; + double m_height; + double m_scale; + double m_scale_inv; + }; + + + + //======================================================line_image_pattern + template<class Filter> class line_image_pattern + { + public: + typedef Filter filter_type; + typedef typename filter_type::color_type color_type; + + //-------------------------------------------------------------------- + line_image_pattern(Filter& filter) : + m_filter(&filter), + m_dilation(filter.dilation() + 1), + m_dilation_hr(m_dilation << line_subpixel_shift), + m_data(), + m_width(0), + m_height(0), + m_width_hr(0), + m_half_height_hr(0), + m_offset_y_hr(0) + { + } + + // Create + //-------------------------------------------------------------------- + template<class Source> + line_image_pattern(Filter& filter, const Source& src) : + m_filter(&filter), + m_dilation(filter.dilation() + 1), + m_dilation_hr(m_dilation << line_subpixel_shift), + m_data(), + m_width(0), + m_height(0), + m_width_hr(0), + m_half_height_hr(0), + m_offset_y_hr(0) + { + create(src); + } + + // Create + //-------------------------------------------------------------------- + template<class Source> void create(const Source& src) + { + m_height = uceil(src.height()); + m_width = uceil(src.width()); + m_width_hr = uround(src.width() * line_subpixel_scale); + m_half_height_hr = uround(src.height() * line_subpixel_scale/2); + m_offset_y_hr = m_dilation_hr + m_half_height_hr - line_subpixel_scale/2; + m_half_height_hr += line_subpixel_scale/2; + + m_data.resize((m_width + m_dilation * 2) * (m_height + m_dilation * 2)); + + m_buf.attach(&m_data[0], m_width + m_dilation * 2, + m_height + m_dilation * 2, + m_width + m_dilation * 2); + unsigned x, y; + color_type* d1; + color_type* d2; + for(y = 0; y < m_height; y++) + { + d1 = m_buf.row_ptr(y + m_dilation) + m_dilation; + for(x = 0; x < m_width; x++) + { + *d1++ = src.pixel(x, y); + } + } + + const color_type* s1; + const color_type* s2; + for(y = 0; y < m_dilation; y++) + { + //s1 = m_buf.row_ptr(m_height + m_dilation - 1) + m_dilation; + //s2 = m_buf.row_ptr(m_dilation) + m_dilation; + d1 = m_buf.row_ptr(m_dilation + m_height + y) + m_dilation; + d2 = m_buf.row_ptr(m_dilation - y - 1) + m_dilation; + for(x = 0; x < m_width; x++) + { + //*d1++ = color_type(*s1++, 0); + //*d2++ = color_type(*s2++, 0); + *d1++ = color_type::no_color(); + *d2++ = color_type::no_color(); + } + } + + unsigned h = m_height + m_dilation * 2; + for(y = 0; y < h; y++) + { + s1 = m_buf.row_ptr(y) + m_dilation; + s2 = m_buf.row_ptr(y) + m_dilation + m_width; + d1 = m_buf.row_ptr(y) + m_dilation + m_width; + d2 = m_buf.row_ptr(y) + m_dilation; + + for(x = 0; x < m_dilation; x++) + { + *d1++ = *s1++; + *--d2 = *--s2; + } + } + } + + //-------------------------------------------------------------------- + int pattern_width() const { return m_width_hr; } + int line_width() const { return m_half_height_hr; } + double width() const { return m_height; } + + //-------------------------------------------------------------------- + void pixel(color_type* p, int x, int y) const + { + m_filter->pixel_high_res(m_buf.rows(), + p, + x % m_width_hr + m_dilation_hr, + y + m_offset_y_hr); + } + + //-------------------------------------------------------------------- + const filter_type& filter() const { return *m_filter; } + + private: + line_image_pattern(const line_image_pattern<filter_type>&); + const line_image_pattern<filter_type>& + operator = (const line_image_pattern<filter_type>&); + + protected: + row_ptr_cache<color_type> m_buf; + const filter_type* m_filter; + unsigned m_dilation; + int m_dilation_hr; + pod_array<color_type> m_data; + unsigned m_width; + unsigned m_height; + int m_width_hr; + int m_half_height_hr; + int m_offset_y_hr; + }; + + + + + + + //=================================================line_image_pattern_pow2 + template<class Filter> class line_image_pattern_pow2 : + public line_image_pattern<Filter> + { + public: + typedef Filter filter_type; + typedef typename filter_type::color_type color_type; + typedef line_image_pattern<Filter> base_type; + + //-------------------------------------------------------------------- + line_image_pattern_pow2(Filter& filter) : + line_image_pattern<Filter>(filter), m_mask(line_subpixel_mask) {} + + //-------------------------------------------------------------------- + template<class Source> + line_image_pattern_pow2(Filter& filter, const Source& src) : + line_image_pattern<Filter>(filter), m_mask(line_subpixel_mask) + { + create(src); + } + + //-------------------------------------------------------------------- + template<class Source> void create(const Source& src) + { + line_image_pattern<Filter>::create(src); + m_mask = 1; + while(m_mask < base_type::m_width) + { + m_mask <<= 1; + m_mask |= 1; + } + m_mask <<= line_subpixel_shift - 1; + m_mask |= line_subpixel_mask; + base_type::m_width_hr = m_mask + 1; + } + + //-------------------------------------------------------------------- + void pixel(color_type* p, int x, int y) const + { + base_type::m_filter->pixel_high_res( + base_type::m_buf.rows(), + p, + (x & m_mask) + base_type::m_dilation_hr, + y + base_type::m_offset_y_hr); + } + private: + unsigned m_mask; + }; + + + + + + + + //===================================================distance_interpolator4 + class distance_interpolator4 + { + public: + //--------------------------------------------------------------------- + distance_interpolator4() {} + distance_interpolator4(int x1, int y1, int x2, int y2, + int sx, int sy, int ex, int ey, + int len, double scale, int x, int y) : + m_dx(x2 - x1), + m_dy(y2 - y1), + m_dx_start(line_mr(sx) - line_mr(x1)), + m_dy_start(line_mr(sy) - line_mr(y1)), + m_dx_end(line_mr(ex) - line_mr(x2)), + m_dy_end(line_mr(ey) - line_mr(y2)), + + m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) - + double(y + line_subpixel_scale/2 - y2) * double(m_dx))), + + m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start - + (line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start), + + m_dist_end((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_end - + (line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_end), + m_len(uround(len / scale)) + { + double d = len * scale; + int dx = iround(((x2 - x1) << line_subpixel_shift) / d); + int dy = iround(((y2 - y1) << line_subpixel_shift) / d); + m_dx_pict = -dy; + m_dy_pict = dx; + m_dist_pict = ((x + line_subpixel_scale/2 - (x1 - dy)) * m_dy_pict - + (y + line_subpixel_scale/2 - (y1 + dx)) * m_dx_pict) >> + line_subpixel_shift; + + m_dx <<= line_subpixel_shift; + m_dy <<= line_subpixel_shift; + m_dx_start <<= line_mr_subpixel_shift; + m_dy_start <<= line_mr_subpixel_shift; + m_dx_end <<= line_mr_subpixel_shift; + m_dy_end <<= line_mr_subpixel_shift; + } + + //--------------------------------------------------------------------- + void inc_x() + { + m_dist += m_dy; + m_dist_start += m_dy_start; + m_dist_pict += m_dy_pict; + m_dist_end += m_dy_end; + } + + //--------------------------------------------------------------------- + void dec_x() + { + m_dist -= m_dy; + m_dist_start -= m_dy_start; + m_dist_pict -= m_dy_pict; + m_dist_end -= m_dy_end; + } + + //--------------------------------------------------------------------- + void inc_y() + { + m_dist -= m_dx; + m_dist_start -= m_dx_start; + m_dist_pict -= m_dx_pict; + m_dist_end -= m_dx_end; + } + + //--------------------------------------------------------------------- + void dec_y() + { + m_dist += m_dx; + m_dist_start += m_dx_start; + m_dist_pict += m_dx_pict; + m_dist_end += m_dx_end; + } + + //--------------------------------------------------------------------- + void inc_x(int dy) + { + m_dist += m_dy; + m_dist_start += m_dy_start; + m_dist_pict += m_dy_pict; + m_dist_end += m_dy_end; + if(dy > 0) + { + m_dist -= m_dx; + m_dist_start -= m_dx_start; + m_dist_pict -= m_dx_pict; + m_dist_end -= m_dx_end; + } + if(dy < 0) + { + m_dist += m_dx; + m_dist_start += m_dx_start; + m_dist_pict += m_dx_pict; + m_dist_end += m_dx_end; + } + } + + //--------------------------------------------------------------------- + void dec_x(int dy) + { + m_dist -= m_dy; + m_dist_start -= m_dy_start; + m_dist_pict -= m_dy_pict; + m_dist_end -= m_dy_end; + if(dy > 0) + { + m_dist -= m_dx; + m_dist_start -= m_dx_start; + m_dist_pict -= m_dx_pict; + m_dist_end -= m_dx_end; + } + if(dy < 0) + { + m_dist += m_dx; + m_dist_start += m_dx_start; + m_dist_pict += m_dx_pict; + m_dist_end += m_dx_end; + } + } + + //--------------------------------------------------------------------- + void inc_y(int dx) + { + m_dist -= m_dx; + m_dist_start -= m_dx_start; + m_dist_pict -= m_dx_pict; + m_dist_end -= m_dx_end; + if(dx > 0) + { + m_dist += m_dy; + m_dist_start += m_dy_start; + m_dist_pict += m_dy_pict; + m_dist_end += m_dy_end; + } + if(dx < 0) + { + m_dist -= m_dy; + m_dist_start -= m_dy_start; + m_dist_pict -= m_dy_pict; + m_dist_end -= m_dy_end; + } + } + + //--------------------------------------------------------------------- + void dec_y(int dx) + { + m_dist += m_dx; + m_dist_start += m_dx_start; + m_dist_pict += m_dx_pict; + m_dist_end += m_dx_end; + if(dx > 0) + { + m_dist += m_dy; + m_dist_start += m_dy_start; + m_dist_pict += m_dy_pict; + m_dist_end += m_dy_end; + } + if(dx < 0) + { + m_dist -= m_dy; + m_dist_start -= m_dy_start; + m_dist_pict -= m_dy_pict; + m_dist_end -= m_dy_end; + } + } + + //--------------------------------------------------------------------- + int dist() const { return m_dist; } + int dist_start() const { return m_dist_start; } + int dist_pict() const { return m_dist_pict; } + int dist_end() const { return m_dist_end; } + + //--------------------------------------------------------------------- + int dx() const { return m_dx; } + int dy() const { return m_dy; } + int dx_start() const { return m_dx_start; } + int dy_start() const { return m_dy_start; } + int dx_pict() const { return m_dx_pict; } + int dy_pict() const { return m_dy_pict; } + int dx_end() const { return m_dx_end; } + int dy_end() const { return m_dy_end; } + int len() const { return m_len; } + + private: + //--------------------------------------------------------------------- + int m_dx; + int m_dy; + int m_dx_start; + int m_dy_start; + int m_dx_pict; + int m_dy_pict; + int m_dx_end; + int m_dy_end; + + int m_dist; + int m_dist_start; + int m_dist_pict; + int m_dist_end; + int m_len; + }; + + + + + + //==================================================line_interpolator_image + template<class Renderer> class line_interpolator_image + { + public: + typedef Renderer renderer_type; + typedef typename Renderer::color_type color_type; + + //--------------------------------------------------------------------- + enum max_half_width_e + { + max_half_width = 64 + }; + + //--------------------------------------------------------------------- + line_interpolator_image(renderer_type& ren, const line_parameters& lp, + int sx, int sy, int ex, int ey, + int pattern_start, + double scale_x) : + m_lp(lp), + m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) : + line_dbl_hr(lp.y2 - lp.y1), + lp.vertical ? std::abs(lp.y2 - lp.y1) : + std::abs(lp.x2 - lp.x1) + 1), + m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.len, scale_x, + lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask), + m_ren(ren), + m_x(lp.x1 >> line_subpixel_shift), + m_y(lp.y1 >> line_subpixel_shift), + m_old_x(m_x), + m_old_y(m_y), + m_count((lp.vertical ? std::abs((lp.y2 >> line_subpixel_shift) - m_y) : + std::abs((lp.x2 >> line_subpixel_shift) - m_x))), + m_width(ren.subpixel_width()), + //m_max_extent(m_width >> (line_subpixel_shift - 2)), + m_max_extent((m_width + line_subpixel_scale) >> line_subpixel_shift), + m_start(pattern_start + (m_max_extent + 2) * ren.pattern_width()), + m_step(0) + { + agg::dda2_line_interpolator li(0, lp.vertical ? + (lp.dy << agg::line_subpixel_shift) : + (lp.dx << agg::line_subpixel_shift), + lp.len); + + unsigned i; + int stop = m_width + line_subpixel_scale * 2; + for(i = 0; i < max_half_width; ++i) + { + m_dist_pos[i] = li.y(); + if(m_dist_pos[i] >= stop) break; + ++li; + } + m_dist_pos[i] = 0x7FFF0000; + + int dist1_start; + int dist2_start; + int npix = 1; + + if(lp.vertical) + { + do + { + --m_li; + m_y -= lp.inc; + m_x = (m_lp.x1 + m_li.y()) >> line_subpixel_shift; + + if(lp.inc > 0) m_di.dec_y(m_x - m_old_x); + else m_di.inc_y(m_x - m_old_x); + + m_old_x = m_x; + + dist1_start = dist2_start = m_di.dist_start(); + + int dx = 0; + if(dist1_start < 0) ++npix; + do + { + dist1_start += m_di.dy_start(); + dist2_start -= m_di.dy_start(); + if(dist1_start < 0) ++npix; + if(dist2_start < 0) ++npix; + ++dx; + } + while(m_dist_pos[dx] <= m_width); + if(npix == 0) break; + + npix = 0; + } + while(--m_step >= -m_max_extent); + } + else + { + do + { + --m_li; + + m_x -= lp.inc; + m_y = (m_lp.y1 + m_li.y()) >> line_subpixel_shift; + + if(lp.inc > 0) m_di.dec_x(m_y - m_old_y); + else m_di.inc_x(m_y - m_old_y); + + m_old_y = m_y; + + dist1_start = dist2_start = m_di.dist_start(); + + int dy = 0; + if(dist1_start < 0) ++npix; + do + { + dist1_start -= m_di.dx_start(); + dist2_start += m_di.dx_start(); + if(dist1_start < 0) ++npix; + if(dist2_start < 0) ++npix; + ++dy; + } + while(m_dist_pos[dy] <= m_width); + if(npix == 0) break; + + npix = 0; + } + while(--m_step >= -m_max_extent); + } + m_li.adjust_forward(); + m_step -= m_max_extent; + } + + //--------------------------------------------------------------------- + bool step_hor() + { + ++m_li; + m_x += m_lp.inc; + m_y = (m_lp.y1 + m_li.y()) >> line_subpixel_shift; + + if(m_lp.inc > 0) m_di.inc_x(m_y - m_old_y); + else m_di.dec_x(m_y - m_old_y); + + m_old_y = m_y; + + int s1 = m_di.dist() / m_lp.len; + int s2 = -s1; + + if(m_lp.inc < 0) s1 = -s1; + + int dist_start; + int dist_pict; + int dist_end; + int dy; + int dist; + + dist_start = m_di.dist_start(); + dist_pict = m_di.dist_pict() + m_start; + dist_end = m_di.dist_end(); + color_type* p0 = m_colors + max_half_width + 2; + color_type* p1 = p0; + + int npix = 0; + p1->clear(); + if(dist_end > 0) + { + if(dist_start <= 0) + { + m_ren.pixel(p1, dist_pict, s2); + } + ++npix; + } + ++p1; + + dy = 1; + while((dist = m_dist_pos[dy]) - s1 <= m_width) + { + dist_start -= m_di.dx_start(); + dist_pict -= m_di.dx_pict(); + dist_end -= m_di.dx_end(); + p1->clear(); + if(dist_end > 0 && dist_start <= 0) + { + if(m_lp.inc > 0) dist = -dist; + m_ren.pixel(p1, dist_pict, s2 - dist); + ++npix; + } + ++p1; + ++dy; + } + + dy = 1; + dist_start = m_di.dist_start(); + dist_pict = m_di.dist_pict() + m_start; + dist_end = m_di.dist_end(); + while((dist = m_dist_pos[dy]) + s1 <= m_width) + { + dist_start += m_di.dx_start(); + dist_pict += m_di.dx_pict(); + dist_end += m_di.dx_end(); + --p0; + p0->clear(); + if(dist_end > 0 && dist_start <= 0) + { + if(m_lp.inc > 0) dist = -dist; + m_ren.pixel(p0, dist_pict, s2 + dist); + ++npix; + } + ++dy; + } + m_ren.blend_color_vspan(m_x, + m_y - dy + 1, + unsigned(p1 - p0), + p0); + return npix && ++m_step < m_count; + } + + + + //--------------------------------------------------------------------- + bool step_ver() + { + ++m_li; + m_y += m_lp.inc; + m_x = (m_lp.x1 + m_li.y()) >> line_subpixel_shift; + + if(m_lp.inc > 0) m_di.inc_y(m_x - m_old_x); + else m_di.dec_y(m_x - m_old_x); + + m_old_x = m_x; + + int s1 = m_di.dist() / m_lp.len; + int s2 = -s1; + + if(m_lp.inc > 0) s1 = -s1; + + int dist_start; + int dist_pict; + int dist_end; + int dist; + int dx; + + dist_start = m_di.dist_start(); + dist_pict = m_di.dist_pict() + m_start; + dist_end = m_di.dist_end(); + color_type* p0 = m_colors + max_half_width + 2; + color_type* p1 = p0; + + int npix = 0; + p1->clear(); + if(dist_end > 0) + { + if(dist_start <= 0) + { + m_ren.pixel(p1, dist_pict, s2); + } + ++npix; + } + ++p1; + + dx = 1; + while((dist = m_dist_pos[dx]) - s1 <= m_width) + { + dist_start += m_di.dy_start(); + dist_pict += m_di.dy_pict(); + dist_end += m_di.dy_end(); + p1->clear(); + if(dist_end > 0 && dist_start <= 0) + { + if(m_lp.inc > 0) dist = -dist; + m_ren.pixel(p1, dist_pict, s2 + dist); + ++npix; + } + ++p1; + ++dx; + } + + dx = 1; + dist_start = m_di.dist_start(); + dist_pict = m_di.dist_pict() + m_start; + dist_end = m_di.dist_end(); + while((dist = m_dist_pos[dx]) + s1 <= m_width) + { + dist_start -= m_di.dy_start(); + dist_pict -= m_di.dy_pict(); + dist_end -= m_di.dy_end(); + --p0; + p0->clear(); + if(dist_end > 0 && dist_start <= 0) + { + if(m_lp.inc > 0) dist = -dist; + m_ren.pixel(p0, dist_pict, s2 - dist); + ++npix; + } + ++dx; + } + m_ren.blend_color_hspan(m_x - dx + 1, + m_y, + unsigned(p1 - p0), + p0); + return npix && ++m_step < m_count; + } + + + //--------------------------------------------------------------------- + int pattern_end() const { return m_start + m_di.len(); } + + //--------------------------------------------------------------------- + bool vertical() const { return m_lp.vertical; } + int width() const { return m_width; } + int count() const { return m_count; } + + private: + line_interpolator_image(const line_interpolator_image<Renderer>&); + const line_interpolator_image<Renderer>& + operator = (const line_interpolator_image<Renderer>&); + + protected: + const line_parameters& m_lp; + dda2_line_interpolator m_li; + distance_interpolator4 m_di; + renderer_type& m_ren; + int m_plen; + int m_x; + int m_y; + int m_old_x; + int m_old_y; + int m_count; + int m_width; + int m_max_extent; + int m_start; + int m_step; + int m_dist_pos[max_half_width + 1]; + color_type m_colors[max_half_width * 2 + 4]; + }; + + + + + + + + + //===================================================renderer_outline_image + template<class BaseRenderer, class ImagePattern> + class renderer_outline_image + { + public: + //--------------------------------------------------------------------- + typedef BaseRenderer base_ren_type; + typedef renderer_outline_image<BaseRenderer, ImagePattern> self_type; + typedef typename base_ren_type::color_type color_type; + typedef ImagePattern pattern_type; + + + //--------------------------------------------------------------------- + renderer_outline_image(base_ren_type& ren, pattern_type& patt) : + m_ren(&ren), + m_pattern(&patt), + m_start(0), + m_scale_x(1.0), + m_clip_box(0,0,0,0), + m_clipping(false) + {} + void attach(base_ren_type& ren) { m_ren = &ren; } + + //--------------------------------------------------------------------- + void pattern(pattern_type& p) { m_pattern = &p; } + pattern_type& pattern() const { return *m_pattern; } + + //--------------------------------------------------------------------- + void reset_clipping() { m_clipping = false; } + void clip_box(double x1, double y1, double x2, double y2) + { + m_clip_box.x1 = line_coord_sat::conv(x1); + m_clip_box.y1 = line_coord_sat::conv(y1); + m_clip_box.x2 = line_coord_sat::conv(x2); + m_clip_box.y2 = line_coord_sat::conv(y2); + m_clipping = true; + } + + //--------------------------------------------------------------------- + void scale_x(double s) { m_scale_x = s; } + double scale_x() const { return m_scale_x; } + + //--------------------------------------------------------------------- + void start_x(double s) { m_start = iround(s * line_subpixel_scale); } + double start_x() const { return double(m_start) / line_subpixel_scale; } + + //--------------------------------------------------------------------- + int subpixel_width() const { return m_pattern->line_width(); } + int pattern_width() const { return m_pattern->pattern_width(); } + double width() const { return double(subpixel_width()) / line_subpixel_scale; } + + //------------------------------------------------------------------------- + void pixel(color_type* p, int x, int y) const + { + m_pattern->pixel(p, x, y); + } + + //------------------------------------------------------------------------- + void blend_color_hspan(int x, int y, unsigned len, const color_type* colors) + { + m_ren->blend_color_hspan(x, y, len, colors, 0); + } + + //------------------------------------------------------------------------- + void blend_color_vspan(int x, int y, unsigned len, const color_type* colors) + { + m_ren->blend_color_vspan(x, y, len, colors, 0); + } + + //------------------------------------------------------------------------- + static bool accurate_join_only() { return true; } + + //------------------------------------------------------------------------- + template<class Cmp> + void semidot(Cmp, int, int, int, int) + { + } + + //------------------------------------------------------------------------- + void pie(int, int, int, int, int, int) + { + } + + //------------------------------------------------------------------------- + void line0(const line_parameters&) + { + } + + //------------------------------------------------------------------------- + void line1(const line_parameters&, int, int) + { + } + + //------------------------------------------------------------------------- + void line2(const line_parameters&, int, int) + { + } + + //------------------------------------------------------------------------- + void line3_no_clip(const line_parameters& lp, + int sx, int sy, int ex, int ey) + { + if(lp.len > line_max_length) + { + line_parameters lp1, lp2; + lp.divide(lp1, lp2); + int mx = lp1.x2 + (lp1.y2 - lp1.y1); + int my = lp1.y2 - (lp1.x2 - lp1.x1); + line3_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1, mx, my); + line3_no_clip(lp2, mx, my, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1); + return; + } + + fix_degenerate_bisectrix_start(lp, &sx, &sy); + fix_degenerate_bisectrix_end(lp, &ex, &ey); + line_interpolator_image<self_type> li(*this, lp, + sx, sy, + ex, ey, + m_start, m_scale_x); + if(li.vertical()) + { + while(li.step_ver()); + } + else + { + while(li.step_hor()); + } + m_start += uround(lp.len / m_scale_x); + } + + //------------------------------------------------------------------------- + void line3(const line_parameters& lp, + int sx, int sy, int ex, int ey) + { + if(m_clipping) + { + int x1 = lp.x1; + int y1 = lp.y1; + int x2 = lp.x2; + int y2 = lp.y2; + unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box); + int start = m_start; + if((flags & 4) == 0) + { + if(flags) + { + line_parameters lp2(x1, y1, x2, y2, + uround(calc_distance(x1, y1, x2, y2))); + if(flags & 1) + { + m_start += uround(calc_distance(lp.x1, lp.y1, x1, y1) / m_scale_x); + sx = x1 + (y2 - y1); + sy = y1 - (x2 - x1); + } + else + { + while(std::abs(sx - lp.x1) + std::abs(sy - lp.y1) > lp2.len) + { + sx = (lp.x1 + sx) >> 1; + sy = (lp.y1 + sy) >> 1; + } + } + if(flags & 2) + { + ex = x2 + (y2 - y1); + ey = y2 - (x2 - x1); + } + else + { + while(std::abs(ex - lp.x2) + std::abs(ey - lp.y2) > lp2.len) + { + ex = (lp.x2 + ex) >> 1; + ey = (lp.y2 + ey) >> 1; + } + } + line3_no_clip(lp2, sx, sy, ex, ey); + } + else + { + line3_no_clip(lp, sx, sy, ex, ey); + } + } + m_start = start + uround(lp.len / m_scale_x); + } + else + { + line3_no_clip(lp, sx, sy, ex, ey); + } + } + + private: + base_ren_type* m_ren; + pattern_type* m_pattern; + int m_start; + double m_scale_x; + rect_i m_clip_box; + bool m_clipping; + }; + + + + + +} + + + +#endif diff --git a/include/agg_renderer_primitives.h b/include/agg_renderer_primitives.h new file mode 100644 index 0000000..f008db7 --- /dev/null +++ b/include/agg_renderer_primitives.h @@ -0,0 +1,224 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class renderer_primitives +// +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERER_PRIMITIVES_INCLUDED +#define AGG_RENDERER_PRIMITIVES_INCLUDED + +#include "agg_basics.h" +#include "agg_renderer_base.h" +#include "agg_dda_line.h" +#include "agg_ellipse_bresenham.h" + +namespace agg +{ + //-----------------------------------------------------renderer_primitives + template<class BaseRenderer> class renderer_primitives + { + public: + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; + + //-------------------------------------------------------------------- + explicit renderer_primitives(base_ren_type& ren) : + m_ren(&ren), + m_fill_color(), + m_line_color(), + m_curr_x(0), + m_curr_y(0) + {} + void attach(base_ren_type& ren) { m_ren = &ren; } + + //-------------------------------------------------------------------- + static int coord(double c) + { + return iround(c * line_bresenham_interpolator::subpixel_scale); + } + + //-------------------------------------------------------------------- + void fill_color(const color_type& c) { m_fill_color = c; } + void line_color(const color_type& c) { m_line_color = c; } + const color_type& fill_color() const { return m_fill_color; } + const color_type& line_color() const { return m_line_color; } + + //-------------------------------------------------------------------- + void rectangle(int x1, int y1, int x2, int y2) + { + m_ren->blend_hline(x1, y1, x2-1, m_line_color, cover_full); + m_ren->blend_vline(x2, y1, y2-1, m_line_color, cover_full); + m_ren->blend_hline(x1+1, y2, x2, m_line_color, cover_full); + m_ren->blend_vline(x1, y1+1, y2, m_line_color, cover_full); + } + + //-------------------------------------------------------------------- + void solid_rectangle(int x1, int y1, int x2, int y2) + { + m_ren->blend_bar(x1, y1, x2, y2, m_fill_color, cover_full); + } + + //-------------------------------------------------------------------- + void outlined_rectangle(int x1, int y1, int x2, int y2) + { + rectangle(x1, y1, x2, y2); + m_ren->blend_bar(x1+1, y1+1, x2-1, y2-1, m_fill_color, cover_full); + } + + //-------------------------------------------------------------------- + void ellipse(int x, int y, int rx, int ry) + { + ellipse_bresenham_interpolator ei(rx, ry); + int dx = 0; + int dy = -ry; + do + { + dx += ei.dx(); + dy += ei.dy(); + m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full); + m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full); + m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full); + m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full); + ++ei; + } + while(dy < 0); + } + + //-------------------------------------------------------------------- + void solid_ellipse(int x, int y, int rx, int ry) + { + ellipse_bresenham_interpolator ei(rx, ry); + int dx = 0; + int dy = -ry; + int dy0 = dy; + int dx0 = dx; + + do + { + dx += ei.dx(); + dy += ei.dy(); + + if(dy != dy0) + { + m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full); + m_ren->blend_hline(x-dx0, y-dy0, x+dx0, m_fill_color, cover_full); + } + dx0 = dx; + dy0 = dy; + ++ei; + } + while(dy < 0); + m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full); + } + + //-------------------------------------------------------------------- + void outlined_ellipse(int x, int y, int rx, int ry) + { + ellipse_bresenham_interpolator ei(rx, ry); + int dx = 0; + int dy = -ry; + + do + { + dx += ei.dx(); + dy += ei.dy(); + + m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full); + m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full); + m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full); + m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full); + + if(ei.dy() && dx) + { + m_ren->blend_hline(x-dx+1, y+dy, x+dx-1, m_fill_color, cover_full); + m_ren->blend_hline(x-dx+1, y-dy, x+dx-1, m_fill_color, cover_full); + } + ++ei; + } + while(dy < 0); + } + + //-------------------------------------------------------------------- + void line(int x1, int y1, int x2, int y2, bool last=false) + { + line_bresenham_interpolator li(x1, y1, x2, y2); + + unsigned len = li.len(); + if(len == 0) + { + if(last) + { + m_ren->blend_pixel(li.line_lr(x1), li.line_lr(y1), m_line_color, cover_full); + } + return; + } + + if(last) ++len; + + if(li.is_ver()) + { + do + { + m_ren->blend_pixel(li.x2(), li.y1(), m_line_color, cover_full); + li.vstep(); + } + while(--len); + } + else + { + do + { + m_ren->blend_pixel(li.x1(), li.y2(), m_line_color, cover_full); + li.hstep(); + } + while(--len); + } + } + + //-------------------------------------------------------------------- + void move_to(int x, int y) + { + m_curr_x = x; + m_curr_y = y; + } + + //-------------------------------------------------------------------- + void line_to(int x, int y, bool last=false) + { + line(m_curr_x, m_curr_y, x, y, last); + m_curr_x = x; + m_curr_y = y; + } + + //-------------------------------------------------------------------- + const base_ren_type& ren() const { return *m_ren; } + base_ren_type& ren() { return *m_ren; } + + //-------------------------------------------------------------------- + const rendering_buffer& rbuf() const { return m_ren->rbuf(); } + rendering_buffer& rbuf() { return m_ren->rbuf(); } + + private: + base_ren_type* m_ren; + color_type m_fill_color; + color_type m_line_color; + int m_curr_x; + int m_curr_y; + }; + +} + +#endif diff --git a/include/agg_renderer_raster_text.h b/include/agg_renderer_raster_text.h new file mode 100644 index 0000000..87b43f9 --- /dev/null +++ b/include/agg_renderer_raster_text.h @@ -0,0 +1,264 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERER_RASTER_TEXT_INCLUDED +#define AGG_RENDERER_RASTER_TEXT_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //==============================================renderer_raster_htext_solid + template<class BaseRenderer, class GlyphGenerator> + class renderer_raster_htext_solid + { + public: + typedef BaseRenderer ren_type; + typedef GlyphGenerator glyph_gen_type; + typedef typename glyph_gen_type::glyph_rect glyph_rect; + typedef typename ren_type::color_type color_type; + + renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph) : + m_ren(&ren), + m_glyph(&glyph) + {} + void attach(ren_type& ren) { m_ren = &ren; } + + //-------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + + //-------------------------------------------------------------------- + template<class CharT> + void render_text(double x, double y, const CharT* str, bool flip=false) + { + glyph_rect r; + while(*str) + { + m_glyph->prepare(&r, x, y, *str, flip); + if(r.x2 >= r.x1) + { + int i; + if(flip) + { + for(i = r.y1; i <= r.y2; i++) + { + m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1), + m_color, + m_glyph->span(r.y2 - i)); + } + } + else + { + for(i = r.y1; i <= r.y2; i++) + { + m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1), + m_color, + m_glyph->span(i - r.y1)); + } + } + } + x += r.dx; + y += r.dy; + ++str; + } + } + + private: + ren_type* m_ren; + glyph_gen_type* m_glyph; + color_type m_color; + }; + + + + //=============================================renderer_raster_vtext_solid + template<class BaseRenderer, class GlyphGenerator> + class renderer_raster_vtext_solid + { + public: + typedef BaseRenderer ren_type; + typedef GlyphGenerator glyph_gen_type; + typedef typename glyph_gen_type::glyph_rect glyph_rect; + typedef typename ren_type::color_type color_type; + + renderer_raster_vtext_solid(ren_type& ren, glyph_gen_type& glyph) : + m_ren(&ren), + m_glyph(&glyph) + { + } + + //-------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + + //-------------------------------------------------------------------- + template<class CharT> + void render_text(double x, double y, const CharT* str, bool flip=false) + { + glyph_rect r; + while(*str) + { + m_glyph->prepare(&r, x, y, *str, !flip); + if(r.x2 >= r.x1) + { + int i; + if(flip) + { + for(i = r.y1; i <= r.y2; i++) + { + m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1), + m_color, + m_glyph->span(i - r.y1)); + } + } + else + { + for(i = r.y1; i <= r.y2; i++) + { + m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1), + m_color, + m_glyph->span(r.y2 - i)); + } + } + } + x += r.dx; + y += r.dy; + ++str; + } + } + + private: + ren_type* m_ren; + glyph_gen_type* m_glyph; + color_type m_color; + }; + + + + + + + //===================================================renderer_raster_htext + template<class ScanlineRenderer, class GlyphGenerator> + class renderer_raster_htext + { + public: + typedef ScanlineRenderer ren_type; + typedef GlyphGenerator glyph_gen_type; + typedef typename glyph_gen_type::glyph_rect glyph_rect; + + class scanline_single_span + { + public: + typedef agg::cover_type cover_type; + + //---------------------------------------------------------------- + struct const_span + { + int x; + unsigned len; + const cover_type* covers; + + const_span() {} + const_span(int x_, unsigned len_, const cover_type* covers_) : + x(x_), len(len_), covers(covers_) + {} + }; + + typedef const const_span* const_iterator; + + //---------------------------------------------------------------- + scanline_single_span(int x, int y, unsigned len, + const cover_type* covers) : + m_y(y), + m_span(x, len, covers) + {} + + //---------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return 1; } + const_iterator begin() const { return &m_span; } + + private: + //---------------------------------------------------------------- + int m_y; + const_span m_span; + }; + + + + //-------------------------------------------------------------------- + renderer_raster_htext(ren_type& ren, glyph_gen_type& glyph) : + m_ren(&ren), + m_glyph(&glyph) + { + } + + + //-------------------------------------------------------------------- + template<class CharT> + void render_text(double x, double y, const CharT* str, bool flip=false) + { + glyph_rect r; + while(*str) + { + m_glyph->prepare(&r, x, y, *str, flip); + if(r.x2 >= r.x1) + { + m_ren->prepare(); + int i; + if(flip) + { + for(i = r.y1; i <= r.y2; i++) + { + m_ren->render( + scanline_single_span(r.x1, + i, + (r.x2 - r.x1 + 1), + m_glyph->span(r.y2 - i))); + } + } + else + { + for(i = r.y1; i <= r.y2; i++) + { + m_ren->render( + scanline_single_span(r.x1, + i, + (r.x2 - r.x1 + 1), + m_glyph->span(i - r.y1))); + } + } + } + x += r.dx; + y += r.dy; + ++str; + } + } + + private: + ren_type* m_ren; + glyph_gen_type* m_glyph; + }; + + + + +} + +#endif + diff --git a/include/agg_renderer_scanline.h b/include/agg_renderer_scanline.h new file mode 100644 index 0000000..47d6f11 --- /dev/null +++ b/include/agg_renderer_scanline.h @@ -0,0 +1,855 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERER_SCANLINE_INCLUDED +#define AGG_RENDERER_SCANLINE_INCLUDED + +#include <limits> +#include <cstdlib> +#include <cstring> +#include "agg_basics.h" +#include "agg_renderer_base.h" + +namespace agg +{ + + //================================================render_scanline_aa_solid + template<class Scanline, class BaseRenderer, class ColorT> + void render_scanline_aa_solid(const Scanline& sl, + BaseRenderer& ren, + const ColorT& color) + { + int y = sl.y(); + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + + for(;;) + { + int x = span->x; + if(span->len > 0) + { + ren.blend_solid_hspan(x, y, (unsigned)span->len, + color, + span->covers); + } + else + { + ren.blend_hline(x, y, (unsigned)(x - span->len - 1), + color, + *(span->covers)); + } + if(--num_spans == 0) break; + ++span; + } + } + + //===============================================render_scanlines_aa_solid + template<class Rasterizer, class Scanline, + class BaseRenderer, class ColorT> + void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl, + BaseRenderer& ren, const ColorT& color) + { + if(ras.rewind_scanlines()) + { + // Explicitly convert "color" to the BaseRenderer color type. + // For example, it can be called with color type "rgba", while + // "rgba8" is needed. Otherwise it will be implicitly + // converted in the loop many times. + //---------------------- + typename BaseRenderer::color_type ren_color = color; + + sl.reset(ras.min_x(), ras.max_x()); + while(ras.sweep_scanline(sl)) + { + //render_scanline_aa_solid(sl, ren, ren_color); + + // This code is equivalent to the above call (copy/paste). + // It's just a "manual" optimization for old compilers, + // like Microsoft Visual C++ v6.0 + //------------------------------- + int y = sl.y(); + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + + for(;;) + { + int x = span->x; + if(span->len > 0) + { + ren.blend_solid_hspan(x, y, (unsigned)span->len, + ren_color, + span->covers); + } + else + { + ren.blend_hline(x, y, (unsigned)(x - span->len - 1), + ren_color, + *(span->covers)); + } + if(--num_spans == 0) break; + ++span; + } + } + } + } + + //==============================================renderer_scanline_aa_solid + template<class BaseRenderer> class renderer_scanline_aa_solid + { + public: + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; + + //-------------------------------------------------------------------- + renderer_scanline_aa_solid() : m_ren(0) {} + explicit renderer_scanline_aa_solid(base_ren_type& ren) : m_ren(&ren) {} + void attach(base_ren_type& ren) + { + m_ren = &ren; + } + + //-------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + render_scanline_aa_solid(sl, *m_ren, m_color); + } + + private: + base_ren_type* m_ren; + color_type m_color; + }; + + + + + + + + + + + + + + //======================================================render_scanline_aa + template<class Scanline, class BaseRenderer, + class SpanAllocator, class SpanGenerator> + void render_scanline_aa(const Scanline& sl, BaseRenderer& ren, + SpanAllocator& alloc, SpanGenerator& span_gen) + { + int y = sl.y(); + + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + for(;;) + { + int x = span->x; + int len = span->len; + const typename Scanline::cover_type* covers = span->covers; + + if(len < 0) len = -len; + typename BaseRenderer::color_type* colors = alloc.allocate(len); + span_gen.generate(colors, x, y, len); + ren.blend_color_hspan(x, y, len, colors, + (span->len < 0) ? 0 : covers, *covers); + + if(--num_spans == 0) break; + ++span; + } + } + + //=====================================================render_scanlines_aa + template<class Rasterizer, class Scanline, class BaseRenderer, + class SpanAllocator, class SpanGenerator> + void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, + SpanAllocator& alloc, SpanGenerator& span_gen) + { + if(ras.rewind_scanlines()) + { + sl.reset(ras.min_x(), ras.max_x()); + span_gen.prepare(); + while(ras.sweep_scanline(sl)) + { + render_scanline_aa(sl, ren, alloc, span_gen); + } + } + } + + //====================================================renderer_scanline_aa + template<class BaseRenderer, class SpanAllocator, class SpanGenerator> + class renderer_scanline_aa + { + public: + typedef BaseRenderer base_ren_type; + typedef SpanAllocator alloc_type; + typedef SpanGenerator span_gen_type; + + //-------------------------------------------------------------------- + renderer_scanline_aa() : m_ren(0), m_alloc(0), m_span_gen(0) {} + renderer_scanline_aa(base_ren_type& ren, + alloc_type& alloc, + span_gen_type& span_gen) : + m_ren(&ren), + m_alloc(&alloc), + m_span_gen(&span_gen) + {} + void attach(base_ren_type& ren, + alloc_type& alloc, + span_gen_type& span_gen) + { + m_ren = &ren; + m_alloc = &alloc; + m_span_gen = &span_gen; + } + + //-------------------------------------------------------------------- + void prepare() { m_span_gen->prepare(); } + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + render_scanline_aa(sl, *m_ren, *m_alloc, *m_span_gen); + } + + private: + base_ren_type* m_ren; + alloc_type* m_alloc; + span_gen_type* m_span_gen; + }; + + + + + + + //===============================================render_scanline_bin_solid + template<class Scanline, class BaseRenderer, class ColorT> + void render_scanline_bin_solid(const Scanline& sl, + BaseRenderer& ren, + const ColorT& color) + { + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + for(;;) + { + ren.blend_hline(span->x, + sl.y(), + span->x - 1 + ((span->len < 0) ? + -span->len : + span->len), + color, + cover_full); + if(--num_spans == 0) break; + ++span; + } + } + + //==============================================render_scanlines_bin_solid + template<class Rasterizer, class Scanline, + class BaseRenderer, class ColorT> + void render_scanlines_bin_solid(Rasterizer& ras, Scanline& sl, + BaseRenderer& ren, const ColorT& color) + { + if(ras.rewind_scanlines()) + { + // Explicitly convert "color" to the BaseRenderer color type. + // For example, it can be called with color type "rgba", while + // "rgba8" is needed. Otherwise it will be implicitly + // converted in the loop many times. + //---------------------- + typename BaseRenderer::color_type ren_color(color); + + sl.reset(ras.min_x(), ras.max_x()); + while(ras.sweep_scanline(sl)) + { + //render_scanline_bin_solid(sl, ren, ren_color); + + // This code is equivalent to the above call (copy/paste). + // It's just a "manual" optimization for old compilers, + // like Microsoft Visual C++ v6.0 + //------------------------------- + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + for(;;) + { + ren.blend_hline(span->x, + sl.y(), + span->x - 1 + ((span->len < 0) ? + -span->len : + span->len), + ren_color, + cover_full); + if(--num_spans == 0) break; + ++span; + } + } + } + } + + //=============================================renderer_scanline_bin_solid + template<class BaseRenderer> class renderer_scanline_bin_solid + { + public: + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; + + //-------------------------------------------------------------------- + renderer_scanline_bin_solid() : m_ren(0) {} + explicit renderer_scanline_bin_solid(base_ren_type& ren) : m_ren(&ren) {} + void attach(base_ren_type& ren) + { + m_ren = &ren; + } + + //-------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + render_scanline_bin_solid(sl, *m_ren, m_color); + } + + private: + base_ren_type* m_ren; + color_type m_color; + }; + + + + + + + + + //======================================================render_scanline_bin + template<class Scanline, class BaseRenderer, + class SpanAllocator, class SpanGenerator> + void render_scanline_bin(const Scanline& sl, BaseRenderer& ren, + SpanAllocator& alloc, SpanGenerator& span_gen) + { + int y = sl.y(); + + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + for(;;) + { + int x = span->x; + int len = span->len; + if(len < 0) len = -len; + typename BaseRenderer::color_type* colors = alloc.allocate(len); + span_gen.generate(colors, x, y, len); + ren.blend_color_hspan(x, y, len, colors, 0, cover_full); + if(--num_spans == 0) break; + ++span; + } + } + + //=====================================================render_scanlines_bin + template<class Rasterizer, class Scanline, class BaseRenderer, + class SpanAllocator, class SpanGenerator> + void render_scanlines_bin(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, + SpanAllocator& alloc, SpanGenerator& span_gen) + { + if(ras.rewind_scanlines()) + { + sl.reset(ras.min_x(), ras.max_x()); + span_gen.prepare(); + while(ras.sweep_scanline(sl)) + { + render_scanline_bin(sl, ren, alloc, span_gen); + } + } + } + + //====================================================renderer_scanline_bin + template<class BaseRenderer, class SpanAllocator, class SpanGenerator> + class renderer_scanline_bin + { + public: + typedef BaseRenderer base_ren_type; + typedef SpanAllocator alloc_type; + typedef SpanGenerator span_gen_type; + + //-------------------------------------------------------------------- + renderer_scanline_bin() : m_ren(0), m_alloc(0), m_span_gen(0) {} + renderer_scanline_bin(base_ren_type& ren, + alloc_type& alloc, + span_gen_type& span_gen) : + m_ren(&ren), + m_alloc(&alloc), + m_span_gen(&span_gen) + {} + void attach(base_ren_type& ren, + alloc_type& alloc, + span_gen_type& span_gen) + { + m_ren = &ren; + m_alloc = &alloc; + m_span_gen = &span_gen; + } + + //-------------------------------------------------------------------- + void prepare() { m_span_gen->prepare(); } + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + render_scanline_bin(sl, *m_ren, *m_alloc, *m_span_gen); + } + + private: + base_ren_type* m_ren; + alloc_type* m_alloc; + span_gen_type* m_span_gen; + }; + + + + + + + + + + + //========================================================render_scanlines + template<class Rasterizer, class Scanline, class Renderer> + void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren) + { + if(ras.rewind_scanlines()) + { + sl.reset(ras.min_x(), ras.max_x()); + ren.prepare(); + while(ras.sweep_scanline(sl)) + { + ren.render(sl); + } + } + } + + //========================================================render_all_paths + template<class Rasterizer, class Scanline, class Renderer, + class VertexSource, class ColorStorage, class PathId> + void render_all_paths(Rasterizer& ras, + Scanline& sl, + Renderer& r, + VertexSource& vs, + const ColorStorage& as, + const PathId& path_id, + unsigned num_paths) + { + for(unsigned i = 0; i < num_paths; i++) + { + ras.reset(); + ras.add_path(vs, path_id[i]); + r.color(as[i]); + render_scanlines(ras, sl, r); + } + } + + + + + + + //=============================================render_scanlines_compound + template<class Rasterizer, + class ScanlineAA, + class ScanlineBin, + class BaseRenderer, + class SpanAllocator, + class StyleHandler> + void render_scanlines_compound(Rasterizer& ras, + ScanlineAA& sl_aa, + ScanlineBin& sl_bin, + BaseRenderer& ren, + SpanAllocator& alloc, + StyleHandler& sh) + { + if(ras.rewind_scanlines()) + { + int min_x = ras.min_x(); + int len = ras.max_x() - min_x + 2; + sl_aa.reset(min_x, ras.max_x()); + sl_bin.reset(min_x, ras.max_x()); + + typedef typename BaseRenderer::color_type color_type; + color_type* color_span = alloc.allocate(len * 2); + color_type* mix_buffer = color_span + len; + unsigned num_spans; + + unsigned num_styles; + unsigned style; + bool solid; + while((num_styles = ras.sweep_styles()) > 0) + { + typename ScanlineAA::const_iterator span_aa; + if(num_styles == 1) + { + // Optimization for a single style. Happens often + //------------------------- + if(ras.sweep_scanline(sl_aa, 0)) + { + style = ras.style(0); + if(sh.is_solid(style)) + { + // Just solid fill + //----------------------- + render_scanline_aa_solid(sl_aa, ren, sh.color(style)); + } + else + { + // Arbitrary span generator + //----------------------- + span_aa = sl_aa.begin(); + num_spans = sl_aa.num_spans(); + for(;;) + { + len = span_aa->len; + sh.generate_span(color_span, + span_aa->x, + sl_aa.y(), + len, + style); + + ren.blend_color_hspan(span_aa->x, + sl_aa.y(), + span_aa->len, + color_span, + span_aa->covers); + if(--num_spans == 0) break; + ++span_aa; + } + } + } + } + else + { + if(ras.sweep_scanline(sl_bin, -1)) + { + // Clear the spans of the mix_buffer + //-------------------- + typename ScanlineBin::const_iterator span_bin = sl_bin.begin(); + num_spans = sl_bin.num_spans(); + for(;;) + { + std::memset(mix_buffer + span_bin->x - min_x, + 0, + span_bin->len * sizeof(color_type)); + + if(--num_spans == 0) break; + ++span_bin; + } + + unsigned i; + for(i = 0; i < num_styles; i++) + { + style = ras.style(i); + solid = sh.is_solid(style); + + if(ras.sweep_scanline(sl_aa, i)) + { + color_type* colors; + color_type* cspan; + typename ScanlineAA::cover_type* covers; + span_aa = sl_aa.begin(); + num_spans = sl_aa.num_spans(); + if(solid) + { + // Just solid fill + //----------------------- + for(;;) + { + color_type c = sh.color(style); + len = span_aa->len; + colors = mix_buffer + span_aa->x - min_x; + covers = span_aa->covers; + do + { + if(*covers == cover_full) + { + *colors = c; + } + else + { + colors->add(c, *covers); + } + ++colors; + ++covers; + } + while(--len); + if(--num_spans == 0) break; + ++span_aa; + } + } + else + { + // Arbitrary span generator + //----------------------- + for(;;) + { + len = span_aa->len; + colors = mix_buffer + span_aa->x - min_x; + cspan = color_span; + sh.generate_span(cspan, + span_aa->x, + sl_aa.y(), + len, + style); + covers = span_aa->covers; + do + { + if(*covers == cover_full) + { + *colors = *cspan; + } + else + { + colors->add(*cspan, *covers); + } + ++cspan; + ++colors; + ++covers; + } + while(--len); + if(--num_spans == 0) break; + ++span_aa; + } + } + } + } + + // Emit the blended result as a color hspan + //------------------------- + span_bin = sl_bin.begin(); + num_spans = sl_bin.num_spans(); + for(;;) + { + ren.blend_color_hspan(span_bin->x, + sl_bin.y(), + span_bin->len, + mix_buffer + span_bin->x - min_x, + 0, + cover_full); + if(--num_spans == 0) break; + ++span_bin; + } + } // if(ras.sweep_scanline(sl_bin, -1)) + } // if(num_styles == 1) ... else + } // while((num_styles = ras.sweep_styles()) > 0) + } // if(ras.rewind_scanlines()) + } + + //=======================================render_scanlines_compound_layered + template<class Rasterizer, + class ScanlineAA, + class BaseRenderer, + class SpanAllocator, + class StyleHandler> + void render_scanlines_compound_layered(Rasterizer& ras, + ScanlineAA& sl_aa, + BaseRenderer& ren, + SpanAllocator& alloc, + StyleHandler& sh) + { + if(ras.rewind_scanlines()) + { + int min_x = ras.min_x(); + int len = ras.max_x() - min_x + 2; + sl_aa.reset(min_x, ras.max_x()); + + typedef typename BaseRenderer::color_type color_type; + color_type* color_span = alloc.allocate(len * 2); + color_type* mix_buffer = color_span + len; + cover_type* cover_buffer = ras.allocate_cover_buffer(len); + unsigned num_spans; + + unsigned num_styles; + unsigned style; + bool solid; + while((num_styles = ras.sweep_styles()) > 0) + { + typename ScanlineAA::const_iterator span_aa; + if(num_styles == 1) + { + // Optimization for a single style. Happens often + //------------------------- + if(ras.sweep_scanline(sl_aa, 0)) + { + style = ras.style(0); + if(sh.is_solid(style)) + { + // Just solid fill + //----------------------- + render_scanline_aa_solid(sl_aa, ren, sh.color(style)); + } + else + { + // Arbitrary span generator + //----------------------- + span_aa = sl_aa.begin(); + num_spans = sl_aa.num_spans(); + for(;;) + { + len = span_aa->len; + sh.generate_span(color_span, + span_aa->x, + sl_aa.y(), + len, + style); + + ren.blend_color_hspan(span_aa->x, + sl_aa.y(), + span_aa->len, + color_span, + span_aa->covers); + if(--num_spans == 0) break; + ++span_aa; + } + } + } + } + else + { + int sl_start = ras.scanline_start(); + unsigned sl_len = ras.scanline_length(); + + if(sl_len) + { + std::memset(mix_buffer + sl_start - min_x, + 0, + sl_len * sizeof(color_type)); + + std::memset(cover_buffer + sl_start - min_x, + 0, + sl_len * sizeof(cover_type)); + + int sl_y = std::numeric_limits<int>::max(); + unsigned i; + for(i = 0; i < num_styles; i++) + { + style = ras.style(i); + solid = sh.is_solid(style); + + if(ras.sweep_scanline(sl_aa, i)) + { + unsigned cover; + color_type* colors; + color_type* cspan; + cover_type* src_covers; + cover_type* dst_covers; + span_aa = sl_aa.begin(); + num_spans = sl_aa.num_spans(); + sl_y = sl_aa.y(); + if(solid) + { + // Just solid fill + //----------------------- + for(;;) + { + color_type c = sh.color(style); + len = span_aa->len; + colors = mix_buffer + span_aa->x - min_x; + src_covers = span_aa->covers; + dst_covers = cover_buffer + span_aa->x - min_x; + do + { + cover = *src_covers; + if(*dst_covers + cover > cover_full) + { + cover = cover_full - *dst_covers; + } + if(cover) + { + colors->add(c, cover); + *dst_covers += cover; + } + ++colors; + ++src_covers; + ++dst_covers; + } + while(--len); + if(--num_spans == 0) break; + ++span_aa; + } + } + else + { + // Arbitrary span generator + //----------------------- + for(;;) + { + len = span_aa->len; + colors = mix_buffer + span_aa->x - min_x; + cspan = color_span; + sh.generate_span(cspan, + span_aa->x, + sl_aa.y(), + len, + style); + src_covers = span_aa->covers; + dst_covers = cover_buffer + span_aa->x - min_x; + do + { + cover = *src_covers; + if(*dst_covers + cover > cover_full) + { + cover = cover_full - *dst_covers; + } + if(cover) + { + colors->add(*cspan, cover); + *dst_covers += cover; + } + ++cspan; + ++colors; + ++src_covers; + ++dst_covers; + } + while(--len); + if(--num_spans == 0) break; + ++span_aa; + } + } + } + } + ren.blend_color_hspan(sl_start, + sl_y, + sl_len, + mix_buffer + sl_start - min_x, + 0, + cover_full); + } //if(sl_len) + } //if(num_styles == 1) ... else + } //while((num_styles = ras.sweep_styles()) > 0) + } //if(ras.rewind_scanlines()) + } + + +} + +#endif diff --git a/include/agg_rendering_buffer.h b/include/agg_rendering_buffer.h new file mode 100644 index 0000000..175bcd8 --- /dev/null +++ b/include/agg_rendering_buffer.h @@ -0,0 +1,301 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class rendering_buffer +// +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERING_BUFFER_INCLUDED +#define AGG_RENDERING_BUFFER_INCLUDED + +#include <cstring> +#include "agg_array.h" + +namespace agg +{ + + //===========================================================row_accessor + template<class T> class row_accessor + { + public: + typedef const_row_info<T> row_data; + + //------------------------------------------------------------------- + row_accessor() : + m_buf(0), + m_start(0), + m_width(0), + m_height(0), + m_stride(0) + { + } + + //-------------------------------------------------------------------- + row_accessor(T* buf, unsigned width, unsigned height, int stride) : + m_buf(0), + m_start(0), + m_width(0), + m_height(0), + m_stride(0) + { + attach(buf, width, height, stride); + } + + + //-------------------------------------------------------------------- + void attach(T* buf, unsigned width, unsigned height, int stride) + { + m_buf = m_start = buf; + m_width = width; + m_height = height; + m_stride = stride; + if(stride < 0) + { + m_start = m_buf - (AGG_INT64)(height - 1) * stride; + } + } + + //-------------------------------------------------------------------- + AGG_INLINE T* buf() { return m_buf; } + AGG_INLINE const T* buf() const { return m_buf; } + AGG_INLINE unsigned width() const { return m_width; } + AGG_INLINE unsigned height() const { return m_height; } + AGG_INLINE int stride() const { return m_stride; } + AGG_INLINE unsigned stride_abs() const + { + return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); + } + + //-------------------------------------------------------------------- + AGG_INLINE T* row_ptr(int, int y, unsigned) + { + return m_start + y * (AGG_INT64)m_stride; + } + AGG_INLINE T* row_ptr(int y) { return m_start + y * (AGG_INT64)m_stride; } + AGG_INLINE const T* row_ptr(int y) const { return m_start + y * (AGG_INT64)m_stride; } + AGG_INLINE row_data row (int y) const + { + return row_data(0, m_width-1, row_ptr(y)); + } + + //-------------------------------------------------------------------- + template<class RenBuf> + void copy_from(const RenBuf& src) + { + unsigned h = height(); + if(src.height() < h) h = src.height(); + + unsigned l = stride_abs(); + if(src.stride_abs() < l) l = src.stride_abs(); + + l *= sizeof(T); + + unsigned y; + unsigned w = width(); + for (y = 0; y < h; y++) + { + std::memcpy(row_ptr(0, y, w), src.row_ptr(y), l); + } + } + + //-------------------------------------------------------------------- + void clear(T value) + { + unsigned y; + unsigned w = width(); + unsigned stride = stride_abs(); + for(y = 0; y < height(); y++) + { + T* p = row_ptr(0, y, w); + unsigned x; + for(x = 0; x < stride; x++) + { + *p++ = value; + } + } + } + + private: + //-------------------------------------------------------------------- + T* m_buf; // Pointer to renrdering buffer + T* m_start; // Pointer to first pixel depending on stride + unsigned m_width; // Width in pixels + unsigned m_height; // Height in pixels + int m_stride; // Number of bytes per row. Can be < 0 + }; + + + + + //==========================================================row_ptr_cache + template<class T> class row_ptr_cache + { + public: + typedef const_row_info<T> row_data; + + //------------------------------------------------------------------- + row_ptr_cache() : + m_buf(0), + m_rows(), + m_width(0), + m_height(0), + m_stride(0) + { + } + + //-------------------------------------------------------------------- + row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) : + m_buf(0), + m_rows(), + m_width(0), + m_height(0), + m_stride(0) + { + attach(buf, width, height, stride); + } + + //-------------------------------------------------------------------- + void attach(T* buf, unsigned width, unsigned height, int stride) + { + m_buf = buf; + m_width = width; + m_height = height; + m_stride = stride; + if(height > m_rows.size()) + { + m_rows.resize(height); + } + + T* row_ptr = m_buf; + + if(stride < 0) + { + row_ptr = m_buf - (AGG_INT64)(height - 1) * stride; + } + + T** rows = &m_rows[0]; + + while(height--) + { + *rows++ = row_ptr; + row_ptr += stride; + } + } + + //-------------------------------------------------------------------- + AGG_INLINE T* buf() { return m_buf; } + AGG_INLINE const T* buf() const { return m_buf; } + AGG_INLINE unsigned width() const { return m_width; } + AGG_INLINE unsigned height() const { return m_height; } + AGG_INLINE int stride() const { return m_stride; } + AGG_INLINE unsigned stride_abs() const + { + return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); + } + + //-------------------------------------------------------------------- + AGG_INLINE T* row_ptr(int, int y, unsigned) + { + return m_rows[y]; + } + AGG_INLINE T* row_ptr(int y) { return m_rows[y]; } + AGG_INLINE const T* row_ptr(int y) const { return m_rows[y]; } + AGG_INLINE row_data row (int y) const + { + return row_data(0, m_width-1, m_rows[y]); + } + + //-------------------------------------------------------------------- + T const* const* rows() const { return &m_rows[0]; } + + //-------------------------------------------------------------------- + template<class RenBuf> + void copy_from(const RenBuf& src) + { + unsigned h = height(); + if(src.height() < h) h = src.height(); + + unsigned l = stride_abs(); + if(src.stride_abs() < l) l = src.stride_abs(); + + l *= sizeof(T); + + unsigned y; + unsigned w = width(); + for (y = 0; y < h; y++) + { + std::memcpy(row_ptr(0, y, w), src.row_ptr(y), l); + } + } + + //-------------------------------------------------------------------- + void clear(T value) + { + unsigned y; + unsigned w = width(); + unsigned stride = stride_abs(); + for(y = 0; y < height(); y++) + { + T* p = row_ptr(0, y, w); + unsigned x; + for(x = 0; x < stride; x++) + { + *p++ = value; + } + } + } + + private: + //-------------------------------------------------------------------- + T* m_buf; // Pointer to renrdering buffer + pod_array<T*> m_rows; // Pointers to each row of the buffer + unsigned m_width; // Width in pixels + unsigned m_height; // Height in pixels + int m_stride; // Number of bytes per row. Can be < 0 + }; + + + + + //========================================================rendering_buffer + // + // The definition of the main type for accessing the rows in the frame + // buffer. It provides functionality to navigate to the rows in a + // rectangular matrix, from top to bottom or from bottom to top depending + // on stride. + // + // row_accessor is cheap to create/destroy, but performs one multiplication + // when calling row_ptr(). + // + // row_ptr_cache creates an array of pointers to rows, so, the access + // via row_ptr() may be faster. But it requires memory allocation + // when creating. For example, on typical Intel Pentium hardware + // row_ptr_cache speeds span_image_filter_rgb_nn up to 10% + // + // It's used only in short hand typedefs like pixfmt_rgba32 and can be + // redefined in agg_config.h + // In real applications you can use both, depending on your needs + //------------------------------------------------------------------------ +#ifdef AGG_RENDERING_BUFFER + typedef AGG_RENDERING_BUFFER rendering_buffer; +#else +// typedef row_ptr_cache<int8u> rendering_buffer; + typedef row_accessor<int8u> rendering_buffer; +#endif + +} + + +#endif diff --git a/include/agg_rendering_buffer_dynarow.h b/include/agg_rendering_buffer_dynarow.h new file mode 100644 index 0000000..4ff4b4f --- /dev/null +++ b/include/agg_rendering_buffer_dynarow.h @@ -0,0 +1,138 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class rendering_buffer_dynarow +// +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERING_BUFFER_DYNAROW_INCLUDED +#define AGG_RENDERING_BUFFER_DYNAROW_INCLUDED + +#include <cstring> +#include "agg_array.h" + +namespace agg +{ + + //===============================================rendering_buffer_dynarow + // Rendering buffer class with dynamic allocation of the rows. + // The rows are allocated as needed when requesting for span_ptr(). + // The class automatically calculates min_x and max_x for each row. + // Generally it's more efficient to use this class as a temporary buffer + // for rendering a few lines and then to blend it with another buffer. + // + class rendering_buffer_dynarow + { + public: + typedef row_info<int8u> row_data; + + //------------------------------------------------------------------- + ~rendering_buffer_dynarow() + { + init(0,0,0); + } + + //------------------------------------------------------------------- + rendering_buffer_dynarow() : + m_rows(), + m_width(0), + m_height(0), + m_byte_width(0) + { + } + + // Allocate and clear the buffer + //-------------------------------------------------------------------- + rendering_buffer_dynarow(unsigned width, unsigned height, + unsigned byte_width) : + m_rows(height), + m_width(width), + m_height(height), + m_byte_width(byte_width) + { + std::memset(&m_rows[0], 0, sizeof(row_data) * height); + } + + // Allocate and clear the buffer + //-------------------------------------------------------------------- + void init(unsigned width, unsigned height, unsigned byte_width) + { + unsigned i; + for(i = 0; i < m_height; ++i) + { + pod_allocator<int8u>::deallocate((int8u*)m_rows[i].ptr, m_byte_width); + } + if(width && height) + { + m_width = width; + m_height = height; + m_byte_width = byte_width; + m_rows.resize(height); + std::memset(&m_rows[0], 0, sizeof(row_data) * height); + } + } + + //-------------------------------------------------------------------- + unsigned width() const { return m_width; } + unsigned height() const { return m_height; } + unsigned byte_width() const { return m_byte_width; } + + // The main function used for rendering. Returns pointer to the + // pre-allocated span. Memory for the row is allocated as needed. + //-------------------------------------------------------------------- + int8u* row_ptr(int x, int y, unsigned len) + { + row_data* r = &m_rows[y]; + int x2 = x + len - 1; + if(r->ptr) + { + if(x < r->x1) { r->x1 = x; } + if(x2 > r->x2) { r->x2 = x2; } + } + else + { + int8u* p = pod_allocator<int8u>::allocate(m_byte_width); + r->ptr = p; + r->x1 = x; + r->x2 = x2; + std::memset(p, 0, m_byte_width); + } + return (int8u*)r->ptr; + } + + //-------------------------------------------------------------------- + const int8u* row_ptr(int y) const { return m_rows[y].ptr; } + int8u* row_ptr(int y) { return row_ptr(0, y, m_width); } + row_data row (int y) const { return m_rows[y]; } + + private: + //-------------------------------------------------------------------- + // Prohibit copying + rendering_buffer_dynarow(const rendering_buffer_dynarow&); + const rendering_buffer_dynarow& operator = (const rendering_buffer_dynarow&); + + private: + //-------------------------------------------------------------------- + pod_array<row_data> m_rows; // Pointers to each row of the buffer + unsigned m_width; // Width in pixels + unsigned m_height; // Height in pixels + unsigned m_byte_width; // Width in bytes + }; + + +} + + +#endif diff --git a/include/agg_rounded_rect.h b/include/agg_rounded_rect.h new file mode 100644 index 0000000..fe8d26f --- /dev/null +++ b/include/agg_rounded_rect.h @@ -0,0 +1,72 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Rounded rectangle vertex generator +// +//---------------------------------------------------------------------------- + +#ifndef AGG_ROUNDED_RECT_INCLUDED +#define AGG_ROUNDED_RECT_INCLUDED + +#include "agg_basics.h" +#include "agg_arc.h" + +namespace agg +{ + //------------------------------------------------------------rounded_rect + // + // See Implemantation agg_rounded_rect.cpp + // + class rounded_rect + { + public: + rounded_rect() {} + rounded_rect(double x1, double y1, double x2, double y2, double r); + + void rect(double x1, double y1, double x2, double y2); + void radius(double r); + void radius(double rx, double ry); + void radius(double rx_bottom, double ry_bottom, double rx_top, double ry_top); + void radius(double rx1, double ry1, double rx2, double ry2, + double rx3, double ry3, double rx4, double ry4); + void normalize_radius(); + + void approximation_scale(double s) { m_arc.approximation_scale(s); } + double approximation_scale() const { return m_arc.approximation_scale(); } + + void rewind(unsigned); + unsigned vertex(double* x, double* y); + + private: + double m_x1; + double m_y1; + double m_x2; + double m_y2; + double m_rx1; + double m_ry1; + double m_rx2; + double m_ry2; + double m_rx3; + double m_ry3; + double m_rx4; + double m_ry4; + unsigned m_status; + arc m_arc; + }; + +} + +#endif + diff --git a/include/agg_scanline_bin.h b/include/agg_scanline_bin.h new file mode 100644 index 0000000..6f9f41e --- /dev/null +++ b/include/agg_scanline_bin.h @@ -0,0 +1,264 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Class scanline_bin - binary scanline. +// +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates (scanline32_bin) has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SCANLINE_BIN_INCLUDED +#define AGG_SCANLINE_BIN_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + + //=============================================================scanline_bin + // + // This is binary scaline container which supports the interface + // used in the rasterizer::render(). See description of agg_scanline_u8 + // for details. + // + //------------------------------------------------------------------------ + class scanline_bin + { + public: + typedef int32 coord_type; + + struct span + { + int16 x; + int16 len; + }; + + typedef const span* const_iterator; + + //-------------------------------------------------------------------- + scanline_bin() : + m_last_x(0x7FFFFFF0), + m_spans(), + m_cur_span(0) + { + } + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 3; + if(max_len > m_spans.size()) + { + m_spans.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_cur_span = &m_spans[0]; + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned) + { + if(x == m_last_x+1) + { + m_cur_span->len++; + } + else + { + ++m_cur_span; + m_cur_span->x = (int16)x; + m_cur_span->len = 1; + } + m_last_x = x; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned) + { + if(x == m_last_x+1) + { + m_cur_span->len = (int16)(m_cur_span->len + len); + } + else + { + ++m_cur_span; + m_cur_span->x = (int16)x; + m_cur_span->len = (int16)len; + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const void*) + { + add_span(x, len, 0); + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cur_span = &m_spans[0]; + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } + const_iterator begin() const { return &m_spans[1]; } + + private: + scanline_bin(const scanline_bin&); + const scanline_bin operator = (const scanline_bin&); + + int m_last_x; + int m_y; + pod_array<span> m_spans; + span* m_cur_span; + }; + + + + + + + //===========================================================scanline32_bin + class scanline32_bin + { + public: + typedef int32 coord_type; + + //-------------------------------------------------------------------- + struct span + { + span() {} + span(coord_type x_, coord_type len_) : x(x_), len(len_) {} + + coord_type x; + coord_type len; + }; + typedef pod_bvector<span, 4> span_array_type; + + + //-------------------------------------------------------------------- + class const_iterator + { + public: + const_iterator(const span_array_type& spans) : + m_spans(spans), + m_span_idx(0) + {} + + const span& operator*() const { return m_spans[m_span_idx]; } + const span* operator->() const { return &m_spans[m_span_idx]; } + + void operator ++ () { ++m_span_idx; } + + private: + const span_array_type& m_spans; + unsigned m_span_idx; + }; + + + //-------------------------------------------------------------------- + scanline32_bin() : m_max_len(0), m_last_x(0x7FFFFFF0) {} + + //-------------------------------------------------------------------- + void reset(int, int) + { + m_last_x = 0x7FFFFFF0; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned) + { + if(x == m_last_x+1) + { + m_spans.last().len++; + } + else + { + m_spans.add(span(coord_type(x), 1)); + } + m_last_x = x; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned) + { + if(x == m_last_x+1) + { + m_spans.last().len += coord_type(len); + } + else + { + m_spans.add(span(coord_type(x), coord_type(len))); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const void*) + { + add_span(x, len, 0); + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return m_spans.size(); } + const_iterator begin() const { return const_iterator(m_spans); } + + private: + scanline32_bin(const scanline32_bin&); + const scanline32_bin operator = (const scanline32_bin&); + + unsigned m_max_len; + int m_last_x; + int m_y; + span_array_type m_spans; + }; + + + + + +} + + +#endif diff --git a/include/agg_scanline_boolean_algebra.h b/include/agg_scanline_boolean_algebra.h new file mode 100644 index 0000000..572c31c --- /dev/null +++ b/include/agg_scanline_boolean_algebra.h @@ -0,0 +1,1566 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_SCANLINE_BOOLEAN_ALGEBRA_INCLUDED +#define AGG_SCANLINE_BOOLEAN_ALGEBRA_INCLUDED + +#include <cstdlib> +#include "agg_basics.h" + + +namespace agg +{ + + //-----------------------------------------------sbool_combine_spans_bin + // Functor. + // Combine two binary encoded spans, i.e., when we don't have any + // anti-aliasing information, but only X and Length. The function + // is compatible with any type of scanlines. + //---------------- + template<class Scanline1, + class Scanline2, + class Scanline> + struct sbool_combine_spans_bin + { + void operator () (const typename Scanline1::const_iterator&, + const typename Scanline2::const_iterator&, + int x, unsigned len, + Scanline& sl) const + { + sl.add_span(x, len, cover_full); + } + }; + + + + //---------------------------------------------sbool_combine_spans_empty + // Functor. + // Combine two spans as empty ones. The functor does nothing + // and is used to XOR binary spans. + //---------------- + template<class Scanline1, + class Scanline2, + class Scanline> + struct sbool_combine_spans_empty + { + void operator () (const typename Scanline1::const_iterator&, + const typename Scanline2::const_iterator&, + int, unsigned, + Scanline&) const + {} + }; + + + + //--------------------------------------------------sbool_add_span_empty + // Functor. + // Add nothing. Used in conbine_shapes_sub + //---------------- + template<class Scanline1, + class Scanline> + struct sbool_add_span_empty + { + void operator () (const typename Scanline1::const_iterator&, + int, unsigned, + Scanline&) const + {} + }; + + + //----------------------------------------------------sbool_add_span_bin + // Functor. + // Add a binary span + //---------------- + template<class Scanline1, + class Scanline> + struct sbool_add_span_bin + { + void operator () (const typename Scanline1::const_iterator&, + int x, unsigned len, + Scanline& sl) const + { + sl.add_span(x, len, cover_full); + } + }; + + + + + //-----------------------------------------------------sbool_add_span_aa + // Functor. + // Add an anti-aliased span + // anti-aliasing information, but only X and Length. The function + // is compatible with any type of scanlines. + //---------------- + template<class Scanline1, + class Scanline> + struct sbool_add_span_aa + { + void operator () (const typename Scanline1::const_iterator& span, + int x, unsigned len, + Scanline& sl) const + { + if(span->len < 0) + { + sl.add_span(x, len, *span->covers); + } + else + if(span->len > 0) + { + const typename Scanline1::cover_type* covers = span->covers; + if(span->x < x) covers += x - span->x; + sl.add_cells(x, len, covers); + } + } + }; + + + + + //----------------------------------------------sbool_intersect_spans_aa + // Functor. + // Intersect two spans preserving the anti-aliasing information. + // The result is added to the "sl" scanline. + //------------------ + template<class Scanline1, + class Scanline2, + class Scanline, + unsigned CoverShift = cover_shift> + struct sbool_intersect_spans_aa + { + enum cover_scale_e + { + cover_shift = CoverShift, + cover_size = 1 << cover_shift, + cover_mask = cover_size - 1, + cover_full = cover_mask + }; + + + void operator () (const typename Scanline1::const_iterator& span1, + const typename Scanline2::const_iterator& span2, + int x, unsigned len, + Scanline& sl) const + { + unsigned cover; + const typename Scanline1::cover_type* covers1; + const typename Scanline2::cover_type* covers2; + + // Calculate the operation code and choose the + // proper combination algorithm. + // 0 = Both spans are of AA type + // 1 = span1 is solid, span2 is AA + // 2 = span1 is AA, span2 is solid + // 3 = Both spans are of solid type + //----------------- + switch((span1->len < 0) | ((span2->len < 0) << 1)) + { + case 0: // Both are AA spans + covers1 = span1->covers; + covers2 = span2->covers; + if(span1->x < x) covers1 += x - span1->x; + if(span2->x < x) covers2 += x - span2->x; + do + { + cover = *covers1++ * *covers2++; + sl.add_cell(x++, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + } + while(--len); + break; + + case 1: // span1 is solid, span2 is AA + covers2 = span2->covers; + if(span2->x < x) covers2 += x - span2->x; + if(*(span1->covers) == cover_full) + { + sl.add_cells(x, len, covers2); + } + else + { + do + { + cover = *(span1->covers) * *covers2++; + sl.add_cell(x++, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + } + while(--len); + } + break; + + case 2: // span1 is AA, span2 is solid + covers1 = span1->covers; + if(span1->x < x) covers1 += x - span1->x; + if(*(span2->covers) == cover_full) + { + sl.add_cells(x, len, covers1); + } + else + { + do + { + cover = *covers1++ * *(span2->covers); + sl.add_cell(x++, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + } + while(--len); + } + break; + + case 3: // Both are solid spans + cover = *(span1->covers) * *(span2->covers); + sl.add_span(x, len, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + break; + } + } + }; + + + + + + + //--------------------------------------------------sbool_unite_spans_aa + // Functor. + // Unite two spans preserving the anti-aliasing information. + // The result is added to the "sl" scanline. + //------------------ + template<class Scanline1, + class Scanline2, + class Scanline, + unsigned CoverShift = cover_shift> + struct sbool_unite_spans_aa + { + enum cover_scale_e + { + cover_shift = CoverShift, + cover_size = 1 << cover_shift, + cover_mask = cover_size - 1, + cover_full = cover_mask + }; + + + void operator () (const typename Scanline1::const_iterator& span1, + const typename Scanline2::const_iterator& span2, + int x, unsigned len, + Scanline& sl) const + { + unsigned cover; + const typename Scanline1::cover_type* covers1; + const typename Scanline2::cover_type* covers2; + + // Calculate the operation code and choose the + // proper combination algorithm. + // 0 = Both spans are of AA type + // 1 = span1 is solid, span2 is AA + // 2 = span1 is AA, span2 is solid + // 3 = Both spans are of solid type + //----------------- + switch((span1->len < 0) | ((span2->len < 0) << 1)) + { + case 0: // Both are AA spans + covers1 = span1->covers; + covers2 = span2->covers; + if(span1->x < x) covers1 += x - span1->x; + if(span2->x < x) covers2 += x - span2->x; + do + { + cover = cover_mask * cover_mask - + (cover_mask - *covers1++) * + (cover_mask - *covers2++); + sl.add_cell(x++, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + } + while(--len); + break; + + case 1: // span1 is solid, span2 is AA + covers2 = span2->covers; + if(span2->x < x) covers2 += x - span2->x; + if(*(span1->covers) == cover_full) + { + sl.add_span(x, len, cover_full); + } + else + { + do + { + cover = cover_mask * cover_mask - + (cover_mask - *(span1->covers)) * + (cover_mask - *covers2++); + sl.add_cell(x++, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + } + while(--len); + } + break; + + case 2: // span1 is AA, span2 is solid + covers1 = span1->covers; + if(span1->x < x) covers1 += x - span1->x; + if(*(span2->covers) == cover_full) + { + sl.add_span(x, len, cover_full); + } + else + { + do + { + cover = cover_mask * cover_mask - + (cover_mask - *covers1++) * + (cover_mask - *(span2->covers)); + sl.add_cell(x++, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + } + while(--len); + } + break; + + case 3: // Both are solid spans + cover = cover_mask * cover_mask - + (cover_mask - *(span1->covers)) * + (cover_mask - *(span2->covers)); + sl.add_span(x, len, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + break; + } + } + }; + + + //---------------------------------------------sbool_xor_formula_linear + template<unsigned CoverShift = cover_shift> + struct sbool_xor_formula_linear + { + enum cover_scale_e + { + cover_shift = CoverShift, + cover_size = 1 << cover_shift, + cover_mask = cover_size - 1 + }; + + static AGG_INLINE unsigned calculate(unsigned a, unsigned b) + { + unsigned cover = a + b; + if(cover > cover_mask) cover = cover_mask + cover_mask - cover; + return cover; + } + }; + + + //---------------------------------------------sbool_xor_formula_saddle + template<unsigned CoverShift = cover_shift> + struct sbool_xor_formula_saddle + { + enum cover_scale_e + { + cover_shift = CoverShift, + cover_size = 1 << cover_shift, + cover_mask = cover_size - 1 + }; + + static AGG_INLINE unsigned calculate(unsigned a, unsigned b) + { + unsigned k = a * b; + if(k == cover_mask * cover_mask) return 0; + + a = (cover_mask * cover_mask - (a << cover_shift) + k) >> cover_shift; + b = (cover_mask * cover_mask - (b << cover_shift) + k) >> cover_shift; + return cover_mask - ((a * b) >> cover_shift); + } + }; + + + //-------------------------------------------sbool_xor_formula_abs_diff + struct sbool_xor_formula_abs_diff + { + static AGG_INLINE unsigned calculate(unsigned a, unsigned b) + { + return unsigned(std::abs(int(a) - int(b))); + } + }; + + + + //----------------------------------------------------sbool_xor_spans_aa + // Functor. + // XOR two spans preserving the anti-aliasing information. + // The result is added to the "sl" scanline. + //------------------ + template<class Scanline1, + class Scanline2, + class Scanline, + class XorFormula, + unsigned CoverShift = cover_shift> + struct sbool_xor_spans_aa + { + enum cover_scale_e + { + cover_shift = CoverShift, + cover_size = 1 << cover_shift, + cover_mask = cover_size - 1, + cover_full = cover_mask + }; + + + void operator () (const typename Scanline1::const_iterator& span1, + const typename Scanline2::const_iterator& span2, + int x, unsigned len, + Scanline& sl) const + { + unsigned cover; + const typename Scanline1::cover_type* covers1; + const typename Scanline2::cover_type* covers2; + + // Calculate the operation code and choose the + // proper combination algorithm. + // 0 = Both spans are of AA type + // 1 = span1 is solid, span2 is AA + // 2 = span1 is AA, span2 is solid + // 3 = Both spans are of solid type + //----------------- + switch((span1->len < 0) | ((span2->len < 0) << 1)) + { + case 0: // Both are AA spans + covers1 = span1->covers; + covers2 = span2->covers; + if(span1->x < x) covers1 += x - span1->x; + if(span2->x < x) covers2 += x - span2->x; + do + { + cover = XorFormula::calculate(*covers1++, *covers2++); + if(cover) sl.add_cell(x, cover); + ++x; + } + while(--len); + break; + + case 1: // span1 is solid, span2 is AA + covers2 = span2->covers; + if(span2->x < x) covers2 += x - span2->x; + do + { + cover = XorFormula::calculate(*(span1->covers), *covers2++); + if(cover) sl.add_cell(x, cover); + ++x; + } + while(--len); + break; + + case 2: // span1 is AA, span2 is solid + covers1 = span1->covers; + if(span1->x < x) covers1 += x - span1->x; + do + { + cover = XorFormula::calculate(*covers1++, *(span2->covers)); + if(cover) sl.add_cell(x, cover); + ++x; + } + while(--len); + break; + + case 3: // Both are solid spans + cover = XorFormula::calculate(*(span1->covers), *(span2->covers)); + if(cover) sl.add_span(x, len, cover); + break; + + } + } + }; + + + + + + //-----------------------------------------------sbool_subtract_spans_aa + // Functor. + // Unite two spans preserving the anti-aliasing information. + // The result is added to the "sl" scanline. + //------------------ + template<class Scanline1, + class Scanline2, + class Scanline, + unsigned CoverShift = cover_shift> + struct sbool_subtract_spans_aa + { + enum cover_scale_e + { + cover_shift = CoverShift, + cover_size = 1 << cover_shift, + cover_mask = cover_size - 1, + cover_full = cover_mask + }; + + + void operator () (const typename Scanline1::const_iterator& span1, + const typename Scanline2::const_iterator& span2, + int x, unsigned len, + Scanline& sl) const + { + unsigned cover; + const typename Scanline1::cover_type* covers1; + const typename Scanline2::cover_type* covers2; + + // Calculate the operation code and choose the + // proper combination algorithm. + // 0 = Both spans are of AA type + // 1 = span1 is solid, span2 is AA + // 2 = span1 is AA, span2 is solid + // 3 = Both spans are of solid type + //----------------- + switch((span1->len < 0) | ((span2->len < 0) << 1)) + { + case 0: // Both are AA spans + covers1 = span1->covers; + covers2 = span2->covers; + if(span1->x < x) covers1 += x - span1->x; + if(span2->x < x) covers2 += x - span2->x; + do + { + cover = *covers1++ * (cover_mask - *covers2++); + if(cover) + { + sl.add_cell(x, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + } + ++x; + } + while(--len); + break; + + case 1: // span1 is solid, span2 is AA + covers2 = span2->covers; + if(span2->x < x) covers2 += x - span2->x; + do + { + cover = *(span1->covers) * (cover_mask - *covers2++); + if(cover) + { + sl.add_cell(x, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + } + ++x; + } + while(--len); + break; + + case 2: // span1 is AA, span2 is solid + covers1 = span1->covers; + if(span1->x < x) covers1 += x - span1->x; + if(*(span2->covers) != cover_full) + { + do + { + cover = *covers1++ * (cover_mask - *(span2->covers)); + if(cover) + { + sl.add_cell(x, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + } + ++x; + } + while(--len); + } + break; + + case 3: // Both are solid spans + cover = *(span1->covers) * (cover_mask - *(span2->covers)); + if(cover) + { + sl.add_span(x, len, + (cover == cover_full * cover_full) ? + cover_full : + (cover >> cover_shift)); + } + break; + } + } + }; + + + + + + + //--------------------------------------------sbool_add_spans_and_render + template<class Scanline1, + class Scanline, + class Renderer, + class AddSpanFunctor> + void sbool_add_spans_and_render(const Scanline1& sl1, + Scanline& sl, + Renderer& ren, + AddSpanFunctor add_span) + { + sl.reset_spans(); + typename Scanline1::const_iterator span = sl1.begin(); + unsigned num_spans = sl1.num_spans(); + for(;;) + { + add_span(span, span->x, std::abs((int)span->len), sl); + if(--num_spans == 0) break; + ++span; + } + sl.finalize(sl1.y()); + ren.render(sl); + } + + + + + + + + //---------------------------------------------sbool_intersect_scanlines + // Intersect two scanlines, "sl1" and "sl2" and generate a new "sl" one. + // The combine_spans functor can be of type sbool_combine_spans_bin or + // sbool_intersect_spans_aa. First is a general functor to combine + // two spans without Anti-Aliasing, the second preserves the AA + // information, but works slower + // + template<class Scanline1, + class Scanline2, + class Scanline, + class CombineSpansFunctor> + void sbool_intersect_scanlines(const Scanline1& sl1, + const Scanline2& sl2, + Scanline& sl, + CombineSpansFunctor combine_spans) + { + sl.reset_spans(); + + unsigned num1 = sl1.num_spans(); + if(num1 == 0) return; + + unsigned num2 = sl2.num_spans(); + if(num2 == 0) return; + + typename Scanline1::const_iterator span1 = sl1.begin(); + typename Scanline2::const_iterator span2 = sl2.begin(); + + while(num1 && num2) + { + int xb1 = span1->x; + int xb2 = span2->x; + int xe1 = xb1 + std::abs((int)span1->len) - 1; + int xe2 = xb2 + std::abs((int)span2->len) - 1; + + // Determine what spans we should advance in the next step + // The span with the least ending X should be advanced + // advance_both is just an optimization when we ending + // coordinates are the same and we can advance both + //-------------- + bool advance_span1 = xe1 < xe2; + bool advance_both = xe1 == xe2; + + // Find the intersection of the spans + // and check if they intersect + //-------------- + if(xb1 < xb2) xb1 = xb2; + if(xe1 > xe2) xe1 = xe2; + if(xb1 <= xe1) + { + combine_spans(span1, span2, xb1, xe1 - xb1 + 1, sl); + } + + // Advance the spans + //-------------- + if(advance_both) + { + --num1; + --num2; + if(num1) ++span1; + if(num2) ++span2; + } + else + { + if(advance_span1) + { + --num1; + if(num1) ++span1; + } + else + { + --num2; + if(num2) ++span2; + } + } + } + } + + + + + + + + + //------------------------------------------------sbool_intersect_shapes + // Intersect the scanline shapes. Here the "Scanline Generator" + // abstraction is used. ScanlineGen1 and ScanlineGen2 are + // the generators, and can be of type rasterizer_scanline_aa<>. + // There function requires three scanline containers that can be of + // different types. + // "sl1" and "sl2" are used to retrieve scanlines from the generators, + // "sl" is ised as the resulting scanline to render it. + // The external "sl1" and "sl2" are used only for the sake of + // optimization and reusing of the scanline objects. + // the function calls sbool_intersect_scanlines with CombineSpansFunctor + // as the last argument. See sbool_intersect_scanlines for details. + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer, + class CombineSpansFunctor> + void sbool_intersect_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren, + CombineSpansFunctor combine_spans) + { + // Prepare the scanline generators. + // If anyone of them doesn't contain + // any scanlines, then return. + //----------------- + if(!sg1.rewind_scanlines()) return; + if(!sg2.rewind_scanlines()) return; + + // Get the bounding boxes + //---------------- + rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y()); + rect_i r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y()); + + // Calculate the intersection of the bounding + // boxes and return if they don't intersect. + //----------------- + rect_i ir = intersect_rectangles(r1, r2); + if(!ir.is_valid()) return; + + // Reset the scanlines and get two first ones + //----------------- + sl.reset(ir.x1, ir.x2); + sl1.reset(sg1.min_x(), sg1.max_x()); + sl2.reset(sg2.min_x(), sg2.max_x()); + if(!sg1.sweep_scanline(sl1)) return; + if(!sg2.sweep_scanline(sl2)) return; + + ren.prepare(); + + // The main loop + // Here we synchronize the scanlines with + // the same Y coordinate, ignoring all other ones. + // Only scanlines having the same Y-coordinate + // are to be combined. + //----------------- + for(;;) + { + while(sl1.y() < sl2.y()) + { + if(!sg1.sweep_scanline(sl1)) return; + } + while(sl2.y() < sl1.y()) + { + if(!sg2.sweep_scanline(sl2)) return; + } + + if(sl1.y() == sl2.y()) + { + // The Y coordinates are the same. + // Combine the scanlines, render if they contain any spans, + // and advance both generators to the next scanlines + //---------------------- + sbool_intersect_scanlines(sl1, sl2, sl, combine_spans); + if(sl.num_spans()) + { + sl.finalize(sl1.y()); + ren.render(sl); + } + if(!sg1.sweep_scanline(sl1)) return; + if(!sg2.sweep_scanline(sl2)) return; + } + } + } + + + + + + + + //-------------------------------------------------sbool_unite_scanlines + // Unite two scanlines, "sl1" and "sl2" and generate a new "sl" one. + // The combine_spans functor can be of type sbool_combine_spans_bin or + // sbool_intersect_spans_aa. First is a general functor to combine + // two spans without Anti-Aliasing, the second preserves the AA + // information, but works slower + // + template<class Scanline1, + class Scanline2, + class Scanline, + class AddSpanFunctor1, + class AddSpanFunctor2, + class CombineSpansFunctor> + void sbool_unite_scanlines(const Scanline1& sl1, + const Scanline2& sl2, + Scanline& sl, + AddSpanFunctor1 add_span1, + AddSpanFunctor2 add_span2, + CombineSpansFunctor combine_spans) + { + sl.reset_spans(); + + unsigned num1 = sl1.num_spans(); + unsigned num2 = sl2.num_spans(); + + typename Scanline1::const_iterator span1;// = sl1.begin(); + typename Scanline2::const_iterator span2;// = sl2.begin(); + + enum invalidation_e + { + invalid_b = 0xFFFFFFF, + invalid_e = invalid_b - 1 + }; + + // Initialize the spans as invalid + //--------------- + int xb1 = invalid_b; + int xb2 = invalid_b; + int xe1 = invalid_e; + int xe2 = invalid_e; + + // Initialize span1 if there are spans + //--------------- + if(num1) + { + span1 = sl1.begin(); + xb1 = span1->x; + xe1 = xb1 + std::abs((int)span1->len) - 1; + --num1; + } + + // Initialize span2 if there are spans + //--------------- + if(num2) + { + span2 = sl2.begin(); + xb2 = span2->x; + xe2 = xb2 + std::abs((int)span2->len) - 1; + --num2; + } + + + for(;;) + { + // Retrieve a new span1 if it's invalid + //---------------- + if(num1 && xb1 > xe1) + { + --num1; + ++span1; + xb1 = span1->x; + xe1 = xb1 + std::abs((int)span1->len) - 1; + } + + // Retrieve a new span2 if it's invalid + //---------------- + if(num2 && xb2 > xe2) + { + --num2; + ++span2; + xb2 = span2->x; + xe2 = xb2 + std::abs((int)span2->len) - 1; + } + + if(xb1 > xe1 && xb2 > xe2) break; + + // Calculate the intersection + //---------------- + int xb = xb1; + int xe = xe1; + if(xb < xb2) xb = xb2; + if(xe > xe2) xe = xe2; + int len = xe - xb + 1; // The length of the intersection + if(len > 0) + { + // The spans intersect, + // add the beginning of the span + //---------------- + if(xb1 < xb2) + { + add_span1(span1, xb1, xb2 - xb1, sl); + xb1 = xb2; + } + else + if(xb2 < xb1) + { + add_span2(span2, xb2, xb1 - xb2, sl); + xb2 = xb1; + } + + // Add the combination part of the spans + //---------------- + combine_spans(span1, span2, xb, len, sl); + + + // Invalidate the fully processed span or both + //---------------- + if(xe1 < xe2) + { + // Invalidate span1 and eat + // the processed part of span2 + //-------------- + xb1 = invalid_b; + xe1 = invalid_e; + xb2 += len; + } + else + if(xe2 < xe1) + { + // Invalidate span2 and eat + // the processed part of span1 + //-------------- + xb2 = invalid_b; + xe2 = invalid_e; + xb1 += len; + } + else + { + xb1 = invalid_b; // Invalidate both + xb2 = invalid_b; + xe1 = invalid_e; + xe2 = invalid_e; + } + } + else + { + // The spans do not intersect + //-------------- + if(xb1 < xb2) + { + // Advance span1 + //--------------- + if(xb1 <= xe1) + { + add_span1(span1, xb1, xe1 - xb1 + 1, sl); + } + xb1 = invalid_b; // Invalidate + xe1 = invalid_e; + } + else + { + // Advance span2 + //--------------- + if(xb2 <= xe2) + { + add_span2(span2, xb2, xe2 - xb2 + 1, sl); + } + xb2 = invalid_b; // Invalidate + xe2 = invalid_e; + } + } + } + } + + + + + //----------------------------------------------------sbool_unite_shapes + // Unite the scanline shapes. Here the "Scanline Generator" + // abstraction is used. ScanlineGen1 and ScanlineGen2 are + // the generators, and can be of type rasterizer_scanline_aa<>. + // There function requires three scanline containers that can be + // of different type. + // "sl1" and "sl2" are used to retrieve scanlines from the generators, + // "sl" is ised as the resulting scanline to render it. + // The external "sl1" and "sl2" are used only for the sake of + // optimization and reusing of the scanline objects. + // the function calls sbool_unite_scanlines with CombineSpansFunctor + // as the last argument. See sbool_unite_scanlines for details. + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer, + class AddSpanFunctor1, + class AddSpanFunctor2, + class CombineSpansFunctor> + void sbool_unite_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren, + AddSpanFunctor1 add_span1, + AddSpanFunctor2 add_span2, + CombineSpansFunctor combine_spans) + { + // Prepare the scanline generators. + // If anyone of them doesn't contain + // any scanlines, then return. + //----------------- + bool flag1 = sg1.rewind_scanlines(); + bool flag2 = sg2.rewind_scanlines(); + if(!flag1 && !flag2) return; + + // Get the bounding boxes + //---------------- + rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y()); + rect_i r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y()); + + // Calculate the union of the bounding boxes + //----------------- + rect_i ur(1,1,0,0); + if(flag1 && flag2) ur = unite_rectangles(r1, r2); + else if(flag1) ur = r1; + else if(flag2) ur = r2; + + if(!ur.is_valid()) return; + + ren.prepare(); + + // Reset the scanlines and get two first ones + //----------------- + sl.reset(ur.x1, ur.x2); + if(flag1) + { + sl1.reset(sg1.min_x(), sg1.max_x()); + flag1 = sg1.sweep_scanline(sl1); + } + + if(flag2) + { + sl2.reset(sg2.min_x(), sg2.max_x()); + flag2 = sg2.sweep_scanline(sl2); + } + + // The main loop + // Here we synchronize the scanlines with + // the same Y coordinate. + //----------------- + while(flag1 || flag2) + { + if(flag1 && flag2) + { + if(sl1.y() == sl2.y()) + { + // The Y coordinates are the same. + // Combine the scanlines, render if they contain any spans, + // and advance both generators to the next scanlines + //---------------------- + sbool_unite_scanlines(sl1, sl2, sl, + add_span1, add_span2, combine_spans); + if(sl.num_spans()) + { + sl.finalize(sl1.y()); + ren.render(sl); + } + flag1 = sg1.sweep_scanline(sl1); + flag2 = sg2.sweep_scanline(sl2); + } + else + { + if(sl1.y() < sl2.y()) + { + sbool_add_spans_and_render(sl1, sl, ren, add_span1); + flag1 = sg1.sweep_scanline(sl1); + } + else + { + sbool_add_spans_and_render(sl2, sl, ren, add_span2); + flag2 = sg2.sweep_scanline(sl2); + } + } + } + else + { + if(flag1) + { + sbool_add_spans_and_render(sl1, sl, ren, add_span1); + flag1 = sg1.sweep_scanline(sl1); + } + if(flag2) + { + sbool_add_spans_and_render(sl2, sl, ren, add_span2); + flag2 = sg2.sweep_scanline(sl2); + } + } + } + } + + + + + + + + + //-------------------------------------------------sbool_subtract_shapes + // Subtract the scanline shapes, "sg1-sg2". Here the "Scanline Generator" + // abstraction is used. ScanlineGen1 and ScanlineGen2 are + // the generators, and can be of type rasterizer_scanline_aa<>. + // There function requires three scanline containers that can be of + // different types. + // "sl1" and "sl2" are used to retrieve scanlines from the generators, + // "sl" is ised as the resulting scanline to render it. + // The external "sl1" and "sl2" are used only for the sake of + // optimization and reusing of the scanline objects. + // the function calls sbool_intersect_scanlines with CombineSpansFunctor + // as the last argument. See combine_scanlines_sub for details. + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer, + class AddSpanFunctor1, + class CombineSpansFunctor> + void sbool_subtract_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren, + AddSpanFunctor1 add_span1, + CombineSpansFunctor combine_spans) + { + // Prepare the scanline generators. + // Here "sg1" is master, "sg2" is slave. + //----------------- + if(!sg1.rewind_scanlines()) return; + bool flag2 = sg2.rewind_scanlines(); + + // Get the bounding box + //---------------- + rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y()); + + // Reset the scanlines and get two first ones + //----------------- + sl.reset(sg1.min_x(), sg1.max_x()); + sl1.reset(sg1.min_x(), sg1.max_x()); + sl2.reset(sg2.min_x(), sg2.max_x()); + if(!sg1.sweep_scanline(sl1)) return; + + if(flag2) flag2 = sg2.sweep_scanline(sl2); + + ren.prepare(); + + // A fake span2 processor + sbool_add_span_empty<Scanline2, Scanline> add_span2; + + // The main loop + // Here we synchronize the scanlines with + // the same Y coordinate, ignoring all other ones. + // Only scanlines having the same Y-coordinate + // are to be combined. + //----------------- + bool flag1 = true; + do + { + // Synchronize "slave" with "master" + //----------------- + while(flag2 && sl2.y() < sl1.y()) + { + flag2 = sg2.sweep_scanline(sl2); + } + + + if(flag2 && sl2.y() == sl1.y()) + { + // The Y coordinates are the same. + // Combine the scanlines and render if they contain any spans. + //---------------------- + sbool_unite_scanlines(sl1, sl2, sl, add_span1, add_span2, combine_spans); + if(sl.num_spans()) + { + sl.finalize(sl1.y()); + ren.render(sl); + } + } + else + { + sbool_add_spans_and_render(sl1, sl, ren, add_span1); + } + + // Advance the "master" + flag1 = sg1.sweep_scanline(sl1); + } + while(flag1); + } + + + + + + + + //---------------------------------------------sbool_intersect_shapes_aa + // Intersect two anti-aliased scanline shapes. + // Here the "Scanline Generator" abstraction is used. + // ScanlineGen1 and ScanlineGen2 are the generators, and can be of + // type rasterizer_scanline_aa<>. There function requires three + // scanline containers that can be of different types. + // "sl1" and "sl2" are used to retrieve scanlines from the generators, + // "sl" is ised as the resulting scanline to render it. + // The external "sl1" and "sl2" are used only for the sake of + // optimization and reusing of the scanline objects. + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_intersect_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_intersect_spans_aa<Scanline1, Scanline2, Scanline> combine_functor; + sbool_intersect_shapes(sg1, sg2, sl1, sl2, sl, ren, combine_functor); + } + + + + + + //--------------------------------------------sbool_intersect_shapes_bin + // Intersect two binary scanline shapes (without anti-aliasing). + // See intersect_shapes_aa for more comments + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_intersect_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_combine_spans_bin<Scanline1, Scanline2, Scanline> combine_functor; + sbool_intersect_shapes(sg1, sg2, sl1, sl2, sl, ren, combine_functor); + } + + + + + + //-------------------------------------------------sbool_unite_shapes_aa + // Unite two anti-aliased scanline shapes + // See intersect_shapes_aa for more comments + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_unite_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_add_span_aa<Scanline1, Scanline> add_functor1; + sbool_add_span_aa<Scanline2, Scanline> add_functor2; + sbool_unite_spans_aa<Scanline1, Scanline2, Scanline> combine_functor; + sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, + add_functor1, add_functor2, combine_functor); + } + + + + + + //------------------------------------------------sbool_unite_shapes_bin + // Unite two binary scanline shapes (without anti-aliasing). + // See intersect_shapes_aa for more comments + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_unite_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_add_span_bin<Scanline1, Scanline> add_functor1; + sbool_add_span_bin<Scanline2, Scanline> add_functor2; + sbool_combine_spans_bin<Scanline1, Scanline2, Scanline> combine_functor; + sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, + add_functor1, add_functor2, combine_functor); + } + + + + + + + + + + //---------------------------------------------------sbool_xor_shapes_aa + // Apply eXclusive OR to two anti-aliased scanline shapes. There's + // a modified "Linear" XOR used instead of classical "Saddle" one. + // The reason is to have the result absolutely conststent with what + // the scanline rasterizer produces. + // See intersect_shapes_aa for more comments + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_xor_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_add_span_aa<Scanline1, Scanline> add_functor1; + sbool_add_span_aa<Scanline2, Scanline> add_functor2; + sbool_xor_spans_aa<Scanline1, Scanline2, Scanline, + sbool_xor_formula_linear<> > combine_functor; + sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, + add_functor1, add_functor2, combine_functor); + } + + + + //------------------------------------------sbool_xor_shapes_saddle_aa + // Apply eXclusive OR to two anti-aliased scanline shapes. + // There's the classical "Saddle" used to calculate the + // Anti-Aliasing values, that is: + // a XOR b : 1-((1-a+a*b)*(1-b+a*b)) + // See intersect_shapes_aa for more comments + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_xor_shapes_saddle_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_add_span_aa<Scanline1, Scanline> add_functor1; + sbool_add_span_aa<Scanline2, Scanline> add_functor2; + sbool_xor_spans_aa<Scanline1, + Scanline2, + Scanline, + sbool_xor_formula_saddle<> > combine_functor; + sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, + add_functor1, add_functor2, combine_functor); + } + + + //--------------------------------------sbool_xor_shapes_abs_diff_aa + // Apply eXclusive OR to two anti-aliased scanline shapes. + // There's the absolute difference used to calculate + // Anti-Aliasing values, that is: + // a XOR b : abs(a-b) + // See intersect_shapes_aa for more comments + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_xor_shapes_abs_diff_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_add_span_aa<Scanline1, Scanline> add_functor1; + sbool_add_span_aa<Scanline2, Scanline> add_functor2; + sbool_xor_spans_aa<Scanline1, + Scanline2, + Scanline, + sbool_xor_formula_abs_diff> combine_functor; + sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, + add_functor1, add_functor2, combine_functor); + } + + + + //--------------------------------------------------sbool_xor_shapes_bin + // Apply eXclusive OR to two binary scanline shapes (without anti-aliasing). + // See intersect_shapes_aa for more comments + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_xor_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_add_span_bin<Scanline1, Scanline> add_functor1; + sbool_add_span_bin<Scanline2, Scanline> add_functor2; + sbool_combine_spans_empty<Scanline1, Scanline2, Scanline> combine_functor; + sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren, + add_functor1, add_functor2, combine_functor); + } + + + + + + + //----------------------------------------------sbool_subtract_shapes_aa + // Subtract shapes "sg1-sg2" with anti-aliasing + // See intersect_shapes_aa for more comments + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_subtract_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_add_span_aa<Scanline1, Scanline> add_functor; + sbool_subtract_spans_aa<Scanline1, Scanline2, Scanline> combine_functor; + sbool_subtract_shapes(sg1, sg2, sl1, sl2, sl, ren, + add_functor, combine_functor); + } + + + + + + //---------------------------------------------sbool_subtract_shapes_bin + // Subtract binary shapes "sg1-sg2" without anti-aliasing + // See intersect_shapes_aa for more comments + //---------- + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_subtract_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + sbool_add_span_bin<Scanline1, Scanline> add_functor; + sbool_combine_spans_empty<Scanline1, Scanline2, Scanline> combine_functor; + sbool_subtract_shapes(sg1, sg2, sl1, sl2, sl, ren, + add_functor, combine_functor); + } + + + + + + + //------------------------------------------------------------sbool_op_e + enum sbool_op_e + { + sbool_or, //----sbool_or + sbool_and, //----sbool_and + sbool_xor, //----sbool_xor + sbool_xor_saddle, //----sbool_xor_saddle + sbool_xor_abs_diff, //----sbool_xor_abs_diff + sbool_a_minus_b, //----sbool_a_minus_b + sbool_b_minus_a //----sbool_b_minus_a + }; + + + + + + + //----------------------------------------------sbool_combine_shapes_bin + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_combine_shapes_bin(sbool_op_e op, + ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + switch(op) + { + case sbool_or : sbool_unite_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break; + case sbool_and : sbool_intersect_shapes_bin(sg1, sg2, sl1, sl2, sl, ren); break; + case sbool_xor : + case sbool_xor_saddle : + case sbool_xor_abs_diff: sbool_xor_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break; + case sbool_a_minus_b : sbool_subtract_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break; + case sbool_b_minus_a : sbool_subtract_shapes_bin (sg2, sg1, sl2, sl1, sl, ren); break; + } + } + + + + + //-----------------------------------------------sbool_combine_shapes_aa + template<class ScanlineGen1, + class ScanlineGen2, + class Scanline1, + class Scanline2, + class Scanline, + class Renderer> + void sbool_combine_shapes_aa(sbool_op_e op, + ScanlineGen1& sg1, ScanlineGen2& sg2, + Scanline1& sl1, Scanline2& sl2, + Scanline& sl, Renderer& ren) + { + switch(op) + { + case sbool_or : sbool_unite_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break; + case sbool_and : sbool_intersect_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break; + case sbool_xor : sbool_xor_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break; + case sbool_xor_saddle : sbool_xor_shapes_saddle_aa (sg1, sg2, sl1, sl2, sl, ren); break; + case sbool_xor_abs_diff: sbool_xor_shapes_abs_diff_aa(sg1, sg2, sl1, sl2, sl, ren); break; + case sbool_a_minus_b : sbool_subtract_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break; + case sbool_b_minus_a : sbool_subtract_shapes_aa (sg2, sg1, sl2, sl1, sl, ren); break; + } + } + +} + + +#endif + diff --git a/include/agg_scanline_p.h b/include/agg_scanline_p.h new file mode 100644 index 0000000..1ddb8c0 --- /dev/null +++ b/include/agg_scanline_p.h @@ -0,0 +1,330 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Class scanline_p - a general purpose scanline container with packed spans. +// +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_SCANLINE_P_INCLUDED +#define AGG_SCANLINE_P_INCLUDED + +#include <cstring> +#include "agg_array.h" + +namespace agg +{ + + //=============================================================scanline_p8 + // + // This is a general purpose scaline container which supports the interface + // used in the rasterizer::render(). See description of scanline_u8 + // for details. + // + //------------------------------------------------------------------------ + class scanline_p8 + { + public: + typedef scanline_p8 self_type; + typedef int8u cover_type; + typedef int16 coord_type; + + //-------------------------------------------------------------------- + struct span + { + coord_type x; + coord_type len; // If negative, it's a solid span, covers is valid + const cover_type* covers; + }; + + typedef span* iterator; + typedef const span* const_iterator; + + scanline_p8() : + m_last_x(0x7FFFFFF0), + m_covers(), + m_cover_ptr(0), + m_spans(), + m_cur_span(0) + { + } + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 3; + if(max_len > m_spans.size()) + { + m_spans.resize(max_len); + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_cur_span = &m_spans[0]; + m_cur_span->len = 0; + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover) + { + *m_cover_ptr = (cover_type)cover; + if(x == m_last_x+1 && m_cur_span->len > 0) + { + m_cur_span->len++; + } + else + { + m_cur_span++; + m_cur_span->covers = m_cover_ptr; + m_cur_span->x = (int16)x; + m_cur_span->len = 1; + } + m_last_x = x; + m_cover_ptr++; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const cover_type* covers) + { + std::memcpy(m_cover_ptr, covers, len * sizeof(cover_type)); + if(x == m_last_x+1 && m_cur_span->len > 0) + { + m_cur_span->len += (int16)len; + } + else + { + m_cur_span++; + m_cur_span->covers = m_cover_ptr; + m_cur_span->x = (int16)x; + m_cur_span->len = (int16)len; + } + m_cover_ptr += len; + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + if(x == m_last_x+1 && + m_cur_span->len < 0 && + cover == *m_cur_span->covers) + { + m_cur_span->len -= (int16)len; + } + else + { + *m_cover_ptr = (cover_type)cover; + m_cur_span++; + m_cur_span->covers = m_cover_ptr++; + m_cur_span->x = (int16)x; + m_cur_span->len = (int16)(-int(len)); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_cur_span = &m_spans[0]; + m_cur_span->len = 0; + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } + const_iterator begin() const { return &m_spans[1]; } + + private: + scanline_p8(const self_type&); + const self_type& operator = (const self_type&); + + int m_last_x; + int m_y; + pod_array<cover_type> m_covers; + cover_type* m_cover_ptr; + pod_array<span> m_spans; + span* m_cur_span; + }; + + + + + + + + + //==========================================================scanline32_p8 + class scanline32_p8 + { + public: + typedef scanline32_p8 self_type; + typedef int8u cover_type; + typedef int32 coord_type; + + struct span + { + span() {} + span(coord_type x_, coord_type len_, const cover_type* covers_) : + x(x_), len(len_), covers(covers_) {} + + coord_type x; + coord_type len; // If negative, it's a solid span, covers is valid + const cover_type* covers; + }; + typedef pod_bvector<span, 4> span_array_type; + + + //-------------------------------------------------------------------- + class const_iterator + { + public: + const_iterator(const span_array_type& spans) : + m_spans(spans), + m_span_idx(0) + {} + + const span& operator*() const { return m_spans[m_span_idx]; } + const span* operator->() const { return &m_spans[m_span_idx]; } + + void operator ++ () { ++m_span_idx; } + + private: + const span_array_type& m_spans; + unsigned m_span_idx; + }; + + //-------------------------------------------------------------------- + scanline32_p8() : + m_max_len(0), + m_last_x(0x7FFFFFF0), + m_covers(), + m_cover_ptr(0) + { + } + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 3; + if(max_len > m_covers.size()) + { + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover) + { + *m_cover_ptr = cover_type(cover); + if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0) + { + m_spans.last().len++; + } + else + { + m_spans.add(span(coord_type(x), 1, m_cover_ptr)); + } + m_last_x = x; + m_cover_ptr++; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const cover_type* covers) + { + std::memcpy(m_cover_ptr, covers, len * sizeof(cover_type)); + if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0) + { + m_spans.last().len += coord_type(len); + } + else + { + m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr)); + } + m_cover_ptr += len; + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + if(x == m_last_x+1 && + m_spans.size() && + m_spans.last().len < 0 && + cover == *m_spans.last().covers) + { + m_spans.last().len -= coord_type(len); + } + else + { + *m_cover_ptr = cover_type(cover); + m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++)); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return m_spans.size(); } + const_iterator begin() const { return const_iterator(m_spans); } + + private: + scanline32_p8(const self_type&); + const self_type& operator = (const self_type&); + + unsigned m_max_len; + int m_last_x; + int m_y; + pod_array<cover_type> m_covers; + cover_type* m_cover_ptr; + span_array_type m_spans; + }; + + +} + + +#endif + diff --git a/include/agg_scanline_storage_aa.h b/include/agg_scanline_storage_aa.h new file mode 100644 index 0000000..6174155 --- /dev/null +++ b/include/agg_scanline_storage_aa.h @@ -0,0 +1,815 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED +#define AGG_SCANLINE_STORAGE_AA_INCLUDED + +#include <cstring> +#include <cstdlib> +#include <limits> +#include "agg_array.h" + + +namespace agg +{ + + //----------------------------------------------scanline_cell_storage + template<class T> class scanline_cell_storage + { + struct extra_span + { + unsigned len; + T* ptr; + }; + + public: + typedef T value_type; + + //--------------------------------------------------------------- + ~scanline_cell_storage() + { + remove_all(); + } + + //--------------------------------------------------------------- + scanline_cell_storage() : + m_cells(128-2), + m_extra_storage() + {} + + + // Copying + //--------------------------------------------------------------- + scanline_cell_storage(const scanline_cell_storage<T>& v) : + m_cells(v.m_cells), + m_extra_storage() + { + copy_extra_storage(v); + } + + //--------------------------------------------------------------- + const scanline_cell_storage<T>& + operator = (const scanline_cell_storage<T>& v) + { + remove_all(); + m_cells = v.m_cells; + copy_extra_storage(v); + return *this; + } + + //--------------------------------------------------------------- + void remove_all() + { + int i; + for(i = m_extra_storage.size()-1; i >= 0; --i) + { + pod_allocator<T>::deallocate(m_extra_storage[i].ptr, + m_extra_storage[i].len); + } + m_extra_storage.remove_all(); + m_cells.remove_all(); + } + + //--------------------------------------------------------------- + int add_cells(const T* cells, unsigned num_cells) + { + int idx = m_cells.allocate_continuous_block(num_cells); + if(idx >= 0) + { + T* ptr = &m_cells[idx]; + std::memcpy(ptr, cells, sizeof(T) * num_cells); + return idx; + } + extra_span s; + s.len = num_cells; + s.ptr = pod_allocator<T>::allocate(num_cells); + std::memcpy(s.ptr, cells, sizeof(T) * num_cells); + m_extra_storage.add(s); + return -int(m_extra_storage.size()); + } + + //--------------------------------------------------------------- + const T* operator [] (int idx) const + { + if(idx >= 0) + { + if((unsigned)idx >= m_cells.size()) return 0; + return &m_cells[(unsigned)idx]; + } + unsigned i = unsigned(-idx - 1); + if(i >= m_extra_storage.size()) return 0; + return m_extra_storage[i].ptr; + } + + //--------------------------------------------------------------- + T* operator [] (int idx) + { + if(idx >= 0) + { + if((unsigned)idx >= m_cells.size()) return 0; + return &m_cells[(unsigned)idx]; + } + unsigned i = unsigned(-idx - 1); + if(i >= m_extra_storage.size()) return 0; + return m_extra_storage[i].ptr; + } + + private: + void copy_extra_storage(const scanline_cell_storage<T>& v) + { + unsigned i; + for(i = 0; i < v.m_extra_storage.size(); ++i) + { + const extra_span& src = v.m_extra_storage[i]; + extra_span dst; + dst.len = src.len; + dst.ptr = pod_allocator<T>::allocate(dst.len); + std::memcpy(dst.ptr, src.ptr, dst.len * sizeof(T)); + m_extra_storage.add(dst); + } + } + + pod_bvector<T, 12> m_cells; + pod_bvector<extra_span, 6> m_extra_storage; + }; + + + + + + + //-----------------------------------------------scanline_storage_aa + template<class T> class scanline_storage_aa + { + public: + typedef T cover_type; + + //--------------------------------------------------------------- + struct span_data + { + int32 x; + int32 len; // If negative, it's a solid span, covers is valid + int covers_id; // The index of the cells in the scanline_cell_storage + }; + + //--------------------------------------------------------------- + struct scanline_data + { + int y; + unsigned num_spans; + unsigned start_span; + }; + + + //--------------------------------------------------------------- + class embedded_scanline + { + public: + + //----------------------------------------------------------- + class const_iterator + { + public: + struct span + { + int32 x; + int32 len; // If negative, it's a solid span, covers is valid + const T* covers; + }; + + const_iterator() : m_storage(0) {} + const_iterator(embedded_scanline& sl) : + m_storage(sl.m_storage), + m_span_idx(sl.m_scanline.start_span) + { + init_span(); + } + + const span& operator*() const { return m_span; } + const span* operator->() const { return &m_span; } + + void operator ++ () + { + ++m_span_idx; + init_span(); + } + + private: + void init_span() + { + const span_data& s = m_storage->span_by_index(m_span_idx); + m_span.x = s.x; + m_span.len = s.len; + m_span.covers = m_storage->covers_by_index(s.covers_id); + } + + scanline_storage_aa* m_storage; + unsigned m_span_idx; + span m_span; + }; + + friend class const_iterator; + + + //----------------------------------------------------------- + embedded_scanline(const scanline_storage_aa& storage) : + m_storage(&storage) + { + init(0); + } + + //----------------------------------------------------------- + void reset(int, int) {} + unsigned num_spans() const { return m_scanline.num_spans; } + int y() const { return m_scanline.y; } + const_iterator begin() const { return const_iterator(*this); } + + //----------------------------------------------------------- + void init(unsigned scanline_idx) + { + m_scanline_idx = scanline_idx; + m_scanline = m_storage->scanline_by_index(m_scanline_idx); + } + + private: + const scanline_storage_aa* m_storage; + scanline_data m_scanline; + unsigned m_scanline_idx; + }; + + + //--------------------------------------------------------------- + scanline_storage_aa() : + m_covers(), + m_spans(256-2), // Block increment size + m_scanlines(), + m_min_x(std::numeric_limits<int>::max()), + m_min_y(std::numeric_limits<int>::max()), + m_max_x(std::numeric_limits<int>::min()), + m_max_y(std::numeric_limits<int>::min()), + m_cur_scanline(0) + { + m_fake_scanline.y = 0; + m_fake_scanline.num_spans = 0; + m_fake_scanline.start_span = 0; + m_fake_span.x = 0; + m_fake_span.len = 0; + m_fake_span.covers_id = 0; + } + + // Renderer Interface + //--------------------------------------------------------------- + void prepare() + { + m_covers.remove_all(); + m_scanlines.remove_all(); + m_spans.remove_all(); + m_min_x = std::numeric_limits<int>::max(); + m_min_y = std::numeric_limits<int>::max(); + m_max_x = std::numeric_limits<int>::min(); + m_max_y = std::numeric_limits<int>::min(); + m_cur_scanline = 0; + } + + //--------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + scanline_data sl_this; + + int y = sl.y(); + if(y < m_min_y) m_min_y = y; + if(y > m_max_y) m_max_y = y; + + sl_this.y = y; + sl_this.num_spans = sl.num_spans(); + sl_this.start_span = m_spans.size(); + typename Scanline::const_iterator span_iterator = sl.begin(); + + unsigned num_spans = sl_this.num_spans; + for(;;) + { + span_data sp; + + sp.x = span_iterator->x; + sp.len = span_iterator->len; + int len = std::abs(int(sp.len)); + sp.covers_id = + m_covers.add_cells(span_iterator->covers, + unsigned(len)); + m_spans.add(sp); + int x1 = sp.x; + int x2 = sp.x + len - 1; + if(x1 < m_min_x) m_min_x = x1; + if(x2 > m_max_x) m_max_x = x2; + if(--num_spans == 0) break; + ++span_iterator; + } + m_scanlines.add(sl_this); + } + + + //--------------------------------------------------------------- + // Iterate scanlines interface + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + //--------------------------------------------------------------- + bool rewind_scanlines() + { + m_cur_scanline = 0; + return m_scanlines.size() > 0; + } + + + //--------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + sl.reset_spans(); + for(;;) + { + if(m_cur_scanline >= m_scanlines.size()) return false; + const scanline_data& sl_this = m_scanlines[m_cur_scanline]; + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + const T* covers = covers_by_index(sp.covers_id); + if(sp.len < 0) + { + sl.add_span(sp.x, unsigned(-sp.len), *covers); + } + else + { + sl.add_cells(sp.x, sp.len, covers); + } + } + while(--num_spans); + ++m_cur_scanline; + if(sl.num_spans()) + { + sl.finalize(sl_this.y); + break; + } + } + return true; + } + + + //--------------------------------------------------------------- + // Specialization for embedded_scanline + bool sweep_scanline(embedded_scanline& sl) + { + do + { + if(m_cur_scanline >= m_scanlines.size()) return false; + sl.init(m_cur_scanline); + ++m_cur_scanline; + } + while(sl.num_spans() == 0); + return true; + } + + //--------------------------------------------------------------- + unsigned byte_size() const + { + unsigned i; + unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y + + for(i = 0; i < m_scanlines.size(); ++i) + { + size += sizeof(int32) * 3; // scanline size in bytes, Y, num_spans + + const scanline_data& sl_this = m_scanlines[i]; + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + + size += sizeof(int32) * 2; // X, span_len + if(sp.len < 0) + { + size += sizeof(T); // cover + } + else + { + size += sizeof(T) * unsigned(sp.len); // covers + } + } + while(--num_spans); + } + return size; + } + + + //--------------------------------------------------------------- + static void write_int32(int8u* dst, int32 val) + { + dst[0] = ((const int8u*)&val)[0]; + dst[1] = ((const int8u*)&val)[1]; + dst[2] = ((const int8u*)&val)[2]; + dst[3] = ((const int8u*)&val)[3]; + } + + + //--------------------------------------------------------------- + void serialize(int8u* data) const + { + unsigned i; + + write_int32(data, min_x()); // min_x + data += sizeof(int32); + write_int32(data, min_y()); // min_y + data += sizeof(int32); + write_int32(data, max_x()); // max_x + data += sizeof(int32); + write_int32(data, max_y()); // max_y + data += sizeof(int32); + + for(i = 0; i < m_scanlines.size(); ++i) + { + const scanline_data& sl_this = m_scanlines[i]; + + int8u* size_ptr = data; + data += sizeof(int32); // Reserve space for scanline size in bytes + + write_int32(data, sl_this.y); // Y + data += sizeof(int32); + + write_int32(data, sl_this.num_spans); // num_spans + data += sizeof(int32); + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + const T* covers = covers_by_index(sp.covers_id); + + write_int32(data, sp.x); // X + data += sizeof(int32); + + write_int32(data, sp.len); // span_len + data += sizeof(int32); + + if(sp.len < 0) + { + std::memcpy(data, covers, sizeof(T)); + data += sizeof(T); + } + else + { + std::memcpy(data, covers, unsigned(sp.len) * sizeof(T)); + data += sizeof(T) * unsigned(sp.len); + } + } + while(--num_spans); + write_int32(size_ptr, int32(unsigned(data - size_ptr))); + } + } + + + //--------------------------------------------------------------- + const scanline_data& scanline_by_index(unsigned i) const + { + return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline; + } + + //--------------------------------------------------------------- + const span_data& span_by_index(unsigned i) const + { + return (i < m_spans.size()) ? m_spans[i] : m_fake_span; + } + + //--------------------------------------------------------------- + const T* covers_by_index(int i) const + { + return m_covers[i]; + } + + private: + scanline_cell_storage<T> m_covers; + pod_bvector<span_data, 10> m_spans; + pod_bvector<scanline_data, 8> m_scanlines; + span_data m_fake_span; + scanline_data m_fake_scanline; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + unsigned m_cur_scanline; + }; + + + typedef scanline_storage_aa<int8u> scanline_storage_aa8; //--------scanline_storage_aa8 + typedef scanline_storage_aa<int16u> scanline_storage_aa16; //--------scanline_storage_aa16 + typedef scanline_storage_aa<int32u> scanline_storage_aa32; //--------scanline_storage_aa32 + + + + + //------------------------------------------serialized_scanlines_adaptor_aa + template<class T> class serialized_scanlines_adaptor_aa + { + public: + typedef T cover_type; + + //--------------------------------------------------------------------- + class embedded_scanline + { + public: + typedef T cover_type; + + //----------------------------------------------------------------- + class const_iterator + { + public: + struct span + { + int32 x; + int32 len; // If negative, it's a solid span, "covers" is valid + const T* covers; + }; + + const_iterator() : m_ptr(0) {} + const_iterator(const embedded_scanline* sl) : + m_ptr(sl->m_ptr), + m_dx(sl->m_dx) + { + init_span(); + } + + const span& operator*() const { return m_span; } + const span* operator->() const { return &m_span; } + + void operator ++ () + { + if(m_span.len < 0) + { + m_ptr += sizeof(T); + } + else + { + m_ptr += m_span.len * sizeof(T); + } + init_span(); + } + + private: + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + void init_span() + { + m_span.x = read_int32() + m_dx; + m_span.len = read_int32(); + m_span.covers = m_ptr; + } + + const int8u* m_ptr; + span m_span; + int m_dx; + }; + + friend class const_iterator; + + + //----------------------------------------------------------------- + embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {} + + //----------------------------------------------------------------- + void reset(int, int) {} + unsigned num_spans() const { return m_num_spans; } + int y() const { return m_y; } + const_iterator begin() const { return const_iterator(this); } + + + private: + //----------------------------------------------------------------- + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + public: + //----------------------------------------------------------------- + void init(const int8u* ptr, int dx, int dy) + { + m_ptr = ptr; + m_y = read_int32() + dy; + m_num_spans = unsigned(read_int32()); + m_dx = dx; + } + + private: + const int8u* m_ptr; + int m_y; + unsigned m_num_spans; + int m_dx; + }; + + + + public: + //-------------------------------------------------------------------- + serialized_scanlines_adaptor_aa() : + m_data(0), + m_end(0), + m_ptr(0), + m_dx(0), + m_dy(0), + m_min_x(std::numeric_limits<int>::max()), + m_min_y(std::numeric_limits<int>::max()), + m_max_x(std::numeric_limits<int>::min()), + m_max_y(std::numeric_limits<int>::min()) + {} + + //-------------------------------------------------------------------- + serialized_scanlines_adaptor_aa(const int8u* data, unsigned size, + double dx, double dy) : + m_data(data), + m_end(data + size), + m_ptr(data), + m_dx(iround(dx)), + m_dy(iround(dy)), + m_min_x(std::numeric_limits<int>::max()), + m_min_y(std::numeric_limits<int>::max()), + m_max_x(std::numeric_limits<int>::min()), + m_max_y(std::numeric_limits<int>::min()) + {} + + //-------------------------------------------------------------------- + void init(const int8u* data, unsigned size, double dx, double dy) + { + m_data = data; + m_end = data + size; + m_ptr = data; + m_dx = iround(dx); + m_dy = iround(dy); + m_min_x = std::numeric_limits<int>::max(); + m_min_y = std::numeric_limits<int>::max(); + m_max_x = std::numeric_limits<int>::min(); + m_max_y = std::numeric_limits<int>::min(); + } + + private: + //-------------------------------------------------------------------- + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + //-------------------------------------------------------------------- + unsigned read_int32u() + { + int32u val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + public: + // Iterate scanlines interface + //-------------------------------------------------------------------- + bool rewind_scanlines() + { + m_ptr = m_data; + if(m_ptr < m_end) + { + m_min_x = read_int32() + m_dx; + m_min_y = read_int32() + m_dy; + m_max_x = read_int32() + m_dx; + m_max_y = read_int32() + m_dy; + } + return m_ptr < m_end; + } + + //-------------------------------------------------------------------- + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + //-------------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + sl.reset_spans(); + for(;;) + { + if(m_ptr >= m_end) return false; + + read_int32(); // Skip scanline size in bytes + int y = read_int32() + m_dy; + unsigned num_spans = read_int32(); + + do + { + int x = read_int32() + m_dx; + int len = read_int32(); + + if(len < 0) + { + sl.add_span(x, unsigned(-len), *m_ptr); + m_ptr += sizeof(T); + } + else + { + sl.add_cells(x, len, m_ptr); + m_ptr += len * sizeof(T); + } + } + while(--num_spans); + + if(sl.num_spans()) + { + sl.finalize(y); + break; + } + } + return true; + } + + + //-------------------------------------------------------------------- + // Specialization for embedded_scanline + bool sweep_scanline(embedded_scanline& sl) + { + do + { + if(m_ptr >= m_end) return false; + + unsigned byte_size = read_int32u(); + sl.init(m_ptr, m_dx, m_dy); + m_ptr += byte_size - sizeof(int32); + } + while(sl.num_spans() == 0); + return true; + } + + private: + const int8u* m_data; + const int8u* m_end; + const int8u* m_ptr; + int m_dx; + int m_dy; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + }; + + + + typedef serialized_scanlines_adaptor_aa<int8u> serialized_scanlines_adaptor_aa8; //----serialized_scanlines_adaptor_aa8 + typedef serialized_scanlines_adaptor_aa<int16u> serialized_scanlines_adaptor_aa16; //----serialized_scanlines_adaptor_aa16 + typedef serialized_scanlines_adaptor_aa<int32u> serialized_scanlines_adaptor_aa32; //----serialized_scanlines_adaptor_aa32 + +} + + +#endif + diff --git a/include/agg_scanline_storage_bin.h b/include/agg_scanline_storage_bin.h new file mode 100644 index 0000000..265df0d --- /dev/null +++ b/include/agg_scanline_storage_bin.h @@ -0,0 +1,585 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + + +#ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED +#define AGG_SCANLINE_STORAGE_BIN_INCLUDED + +#include <cstdlib> +#include <limits> +#include "agg_array.h" + + +namespace agg +{ + + //-----------------------------------------------scanline_storage_bin + class scanline_storage_bin + { + public: + //--------------------------------------------------------------- + struct span_data + { + int32 x; + int32 len; + }; + + //--------------------------------------------------------------- + struct scanline_data + { + int y; + unsigned num_spans; + unsigned start_span; + }; + + + //--------------------------------------------------------------- + class embedded_scanline + { + public: + + //----------------------------------------------------------- + class const_iterator + { + public: + const_iterator() : m_storage(0) {} + const_iterator(const embedded_scanline* sl) : + m_storage(sl->m_storage), + m_span_idx(sl->m_scanline.start_span) + { + m_span = m_storage->span_by_index(m_span_idx); + } + + const span_data& operator*() const { return m_span; } + const span_data* operator->() const { return &m_span; } + + void operator ++ () + { + ++m_span_idx; + m_span = m_storage->span_by_index(m_span_idx); + } + + private: + const scanline_storage_bin* m_storage; + unsigned m_span_idx; + span_data m_span; + }; + + friend class const_iterator; + + + //----------------------------------------------------------- + embedded_scanline(scanline_storage_bin& storage) : + m_storage(&storage) + { + setup(0); + } + + //----------------------------------------------------------- + void reset(int, int) {} + unsigned num_spans() const { return m_scanline.num_spans; } + int y() const { return m_scanline.y; } + const_iterator begin() const { return const_iterator(this); } + + //----------------------------------------------------------- + void setup(unsigned scanline_idx) + { + m_scanline_idx = scanline_idx; + m_scanline = m_storage->scanline_by_index(m_scanline_idx); + } + + private: + scanline_storage_bin* m_storage; + scanline_data m_scanline; + unsigned m_scanline_idx; + }; + + + //--------------------------------------------------------------- + scanline_storage_bin() : + m_spans(256-2), // Block increment size + m_scanlines(), + m_min_x(std::numeric_limits<int>::max()), + m_min_y(std::numeric_limits<int>::max()), + m_max_x(std::numeric_limits<int>::min()), + m_max_y(std::numeric_limits<int>::min()), + m_cur_scanline(0) + { + m_fake_scanline.y = 0; + m_fake_scanline.num_spans = 0; + m_fake_scanline.start_span = 0; + m_fake_span.x = 0; + m_fake_span.len = 0; + } + + // Renderer Interface + //--------------------------------------------------------------- + void prepare() + { + m_scanlines.remove_all(); + m_spans.remove_all(); + m_min_x = std::numeric_limits<int>::max(); + m_min_y = std::numeric_limits<int>::max(); + m_max_x = std::numeric_limits<int>::min(); + m_max_y = std::numeric_limits<int>::min(); + m_cur_scanline = 0; + } + + //--------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + scanline_data sl_this; + + int y = sl.y(); + if(y < m_min_y) m_min_y = y; + if(y > m_max_y) m_max_y = y; + + sl_this.y = y; + sl_this.num_spans = sl.num_spans(); + sl_this.start_span = m_spans.size(); + typename Scanline::const_iterator span_iterator = sl.begin(); + + unsigned num_spans = sl_this.num_spans; + for(;;) + { + span_data sp; + sp.x = span_iterator->x; + sp.len = (int32)std::abs((int)(span_iterator->len)); + m_spans.add(sp); + int x1 = sp.x; + int x2 = sp.x + sp.len - 1; + if(x1 < m_min_x) m_min_x = x1; + if(x2 > m_max_x) m_max_x = x2; + if(--num_spans == 0) break; + ++span_iterator; + } + m_scanlines.add(sl_this); + } + + + //--------------------------------------------------------------- + // Iterate scanlines interface + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + //--------------------------------------------------------------- + bool rewind_scanlines() + { + m_cur_scanline = 0; + return m_scanlines.size() > 0; + } + + + //--------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + sl.reset_spans(); + for(;;) + { + if(m_cur_scanline >= m_scanlines.size()) return false; + const scanline_data& sl_this = m_scanlines[m_cur_scanline]; + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + sl.add_span(sp.x, sp.len, cover_full); + } + while(--num_spans); + + ++m_cur_scanline; + if(sl.num_spans()) + { + sl.finalize(sl_this.y); + break; + } + } + return true; + } + + + //--------------------------------------------------------------- + // Specialization for embedded_scanline + bool sweep_scanline(embedded_scanline& sl) + { + do + { + if(m_cur_scanline >= m_scanlines.size()) return false; + sl.setup(m_cur_scanline); + ++m_cur_scanline; + } + while(sl.num_spans() == 0); + return true; + } + + + //--------------------------------------------------------------- + unsigned byte_size() const + { + unsigned i; + unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y + + for(i = 0; i < m_scanlines.size(); ++i) + { + size += sizeof(int32) * 2 + // Y, num_spans + unsigned(m_scanlines[i].num_spans) * sizeof(int32) * 2; // X, span_len + } + return size; + } + + + //--------------------------------------------------------------- + static void write_int32(int8u* dst, int32 val) + { + dst[0] = ((const int8u*)&val)[0]; + dst[1] = ((const int8u*)&val)[1]; + dst[2] = ((const int8u*)&val)[2]; + dst[3] = ((const int8u*)&val)[3]; + } + + + //--------------------------------------------------------------- + void serialize(int8u* data) const + { + unsigned i; + + write_int32(data, min_x()); // min_x + data += sizeof(int32); + write_int32(data, min_y()); // min_y + data += sizeof(int32); + write_int32(data, max_x()); // max_x + data += sizeof(int32); + write_int32(data, max_y()); // max_y + data += sizeof(int32); + + for(i = 0; i < m_scanlines.size(); ++i) + { + const scanline_data& sl_this = m_scanlines[i]; + + write_int32(data, sl_this.y); // Y + data += sizeof(int32); + + write_int32(data, sl_this.num_spans); // num_spans + data += sizeof(int32); + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + + write_int32(data, sp.x); // X + data += sizeof(int32); + + write_int32(data, sp.len); // len + data += sizeof(int32); + } + while(--num_spans); + } + } + + + //--------------------------------------------------------------- + const scanline_data& scanline_by_index(unsigned i) const + { + return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline; + } + + //--------------------------------------------------------------- + const span_data& span_by_index(unsigned i) const + { + return (i < m_spans.size()) ? m_spans[i] : m_fake_span; + } + + + private: + pod_bvector<span_data, 10> m_spans; + pod_bvector<scanline_data, 8> m_scanlines; + span_data m_fake_span; + scanline_data m_fake_scanline; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + unsigned m_cur_scanline; + }; + + + + + + + + + + + + + + //---------------------------------------serialized_scanlines_adaptor_bin + class serialized_scanlines_adaptor_bin + { + public: + typedef bool cover_type; + + //-------------------------------------------------------------------- + class embedded_scanline + { + public: + + //---------------------------------------------------------------- + class const_iterator + { + public: + struct span + { + int32 x; + int32 len; + }; + + const_iterator() : m_ptr(0) {} + const_iterator(const embedded_scanline* sl) : + m_ptr(sl->m_ptr), + m_dx(sl->m_dx) + { + m_span.x = read_int32() + m_dx; + m_span.len = read_int32(); + } + + const span& operator*() const { return m_span; } + const span* operator->() const { return &m_span; } + + void operator ++ () + { + m_span.x = read_int32() + m_dx; + m_span.len = read_int32(); + } + + private: + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + const int8u* m_ptr; + span m_span; + int m_dx; + }; + + friend class const_iterator; + + + //---------------------------------------------------------------- + embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {} + + //---------------------------------------------------------------- + void reset(int, int) {} + unsigned num_spans() const { return m_num_spans; } + int y() const { return m_y; } + const_iterator begin() const { return const_iterator(this); } + + + private: + //---------------------------------------------------------------- + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + public: + //---------------------------------------------------------------- + void init(const int8u* ptr, int dx, int dy) + { + m_ptr = ptr; + m_y = read_int32() + dy; + m_num_spans = unsigned(read_int32()); + m_dx = dx; + } + + private: + const int8u* m_ptr; + int m_y; + unsigned m_num_spans; + int m_dx; + }; + + + + public: + //-------------------------------------------------------------------- + serialized_scanlines_adaptor_bin() : + m_data(0), + m_end(0), + m_ptr(0), + m_dx(0), + m_dy(0), + m_min_x(std::numeric_limits<int>::max()), + m_min_y(std::numeric_limits<int>::max()), + m_max_x(std::numeric_limits<int>::min()), + m_max_y(std::numeric_limits<int>::min()) + {} + + //-------------------------------------------------------------------- + serialized_scanlines_adaptor_bin(const int8u* data, unsigned size, + double dx, double dy) : + m_data(data), + m_end(data + size), + m_ptr(data), + m_dx(iround(dx)), + m_dy(iround(dy)), + m_min_x(std::numeric_limits<int>::max()), + m_min_y(std::numeric_limits<int>::max()), + m_max_x(std::numeric_limits<int>::min()), + m_max_y(std::numeric_limits<int>::min()) + {} + + //-------------------------------------------------------------------- + void init(const int8u* data, unsigned size, double dx, double dy) + { + m_data = data; + m_end = data + size; + m_ptr = data; + m_dx = iround(dx); + m_dy = iround(dy); + m_min_x = std::numeric_limits<int>::max(); + m_min_y = std::numeric_limits<int>::max(); + m_max_x = std::numeric_limits<int>::min(); + m_max_y = std::numeric_limits<int>::min(); + } + + private: + //-------------------------------------------------------------------- + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + public: + // Iterate scanlines interface + //-------------------------------------------------------------------- + bool rewind_scanlines() + { + m_ptr = m_data; + if(m_ptr < m_end) + { + m_min_x = read_int32() + m_dx; + m_min_y = read_int32() + m_dy; + m_max_x = read_int32() + m_dx; + m_max_y = read_int32() + m_dy; + } + return m_ptr < m_end; + } + + //-------------------------------------------------------------------- + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + //-------------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + sl.reset_spans(); + for(;;) + { + if(m_ptr >= m_end) return false; + + int y = read_int32() + m_dy; + unsigned num_spans = read_int32(); + + do + { + int x = read_int32() + m_dx; + int len = read_int32(); + + if(len < 0) len = -len; + sl.add_span(x, unsigned(len), cover_full); + } + while(--num_spans); + + if(sl.num_spans()) + { + sl.finalize(y); + break; + } + } + return true; + } + + + //-------------------------------------------------------------------- + // Specialization for embedded_scanline + bool sweep_scanline(embedded_scanline& sl) + { + do + { + if(m_ptr >= m_end) return false; + + sl.init(m_ptr, m_dx, m_dy); + + // Jump to the next scanline + //-------------------------- + read_int32(); // Y + int num_spans = read_int32(); // num_spans + m_ptr += num_spans * sizeof(int32) * 2; + } + while(sl.num_spans() == 0); + return true; + } + + private: + const int8u* m_data; + const int8u* m_end; + const int8u* m_ptr; + int m_dx; + int m_dy; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + }; + + + +} + +#endif + diff --git a/include/agg_scanline_u.h b/include/agg_scanline_u.h new file mode 100644 index 0000000..0ca9c68 --- /dev/null +++ b/include/agg_scanline_u.h @@ -0,0 +1,500 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SCANLINE_U_INCLUDED +#define AGG_SCANLINE_U_INCLUDED + +#include <cstring> +#include "agg_array.h" + +namespace agg +{ + //=============================================================scanline_u8 + // + // Unpacked scanline container class + // + // This class is used to transfer data from a scanline rasterizer + // to the rendering buffer. It's organized very simple. The class stores + // information of horizontal spans to render it into a pixel-map buffer. + // Each span has staring X, length, and an array of bytes that determine the + // cover-values for each pixel. + // Before using this class you should know the minimal and maximal pixel + // coordinates of your scanline. The protocol of using is: + // 1. reset(min_x, max_x) + // 2. add_cell() / add_span() - accumulate scanline. + // When forming one scanline the next X coordinate must be always greater + // than the last stored one, i.e. it works only with ordered coordinates. + // 3. Call finalize(y) and render the scanline. + // 3. Call reset_spans() to prepare for the new scanline. + // + // 4. Rendering: + // + // Scanline provides an iterator class that allows you to extract + // the spans and the cover values for each pixel. Be aware that clipping + // has not been done yet, so you should perform it yourself. + // Use scanline_u8::iterator to render spans: + //------------------------------------------------------------------------- + // + // int y = sl.y(); // Y-coordinate of the scanline + // + // ************************************ + // ...Perform vertical clipping here... + // ************************************ + // + // scanline_u8::const_iterator span = sl.begin(); + // + // unsigned char* row = m_rbuf->row(y); // The address of the beginning + // // of the current row + // + // unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that + // // num_spans is always greater than 0. + // + // do + // { + // const scanline_u8::cover_type* covers = + // span->covers; // The array of the cover values + // + // int num_pix = span->len; // Number of pixels of the span. + // // Always greater than 0, still it's + // // better to use "int" instead of + // // "unsigned" because it's more + // // convenient for clipping + // int x = span->x; + // + // ************************************** + // ...Perform horizontal clipping here... + // ...you have x, covers, and pix_count.. + // ************************************** + // + // unsigned char* dst = row + x; // Calculate the start address of the row. + // // In this case we assume a simple + // // grayscale image 1-byte per pixel. + // do + // { + // *dst++ = *covers++; // Hypotetical rendering. + // } + // while(--num_pix); + // + // ++span; + // } + // while(--num_spans); // num_spans cannot be 0, so this loop is quite safe + //------------------------------------------------------------------------ + // + // The question is: why should we accumulate the whole scanline when we + // could render just separate spans when they're ready? + // That's because using the scanline is generally faster. When is consists + // of more than one span the conditions for the processor cash system + // are better, because switching between two different areas of memory + // (that can be very large) occurs less frequently. + //------------------------------------------------------------------------ + class scanline_u8 + { + public: + typedef scanline_u8 self_type; + typedef int8u cover_type; + typedef int16 coord_type; + + //-------------------------------------------------------------------- + struct span + { + coord_type x; + coord_type len; + cover_type* covers; + }; + + typedef span* iterator; + typedef const span* const_iterator; + + //-------------------------------------------------------------------- + scanline_u8() : + m_min_x(0), + m_last_x(0x7FFFFFF0), + m_cur_span(0) + {} + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 2; + if(max_len > m_spans.size()) + { + m_spans.resize(max_len); + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_min_x = min_x; + m_cur_span = &m_spans[0]; + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover) + { + x -= m_min_x; + m_covers[x] = (cover_type)cover; + if(x == m_last_x+1) + { + m_cur_span->len++; + } + else + { + m_cur_span++; + m_cur_span->x = (coord_type)(x + m_min_x); + m_cur_span->len = 1; + m_cur_span->covers = &m_covers[x]; + } + m_last_x = x; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const cover_type* covers) + { + x -= m_min_x; + std::memcpy(&m_covers[x], covers, len * sizeof(cover_type)); + if(x == m_last_x+1) + { + m_cur_span->len += (coord_type)len; + } + else + { + m_cur_span++; + m_cur_span->x = (coord_type)(x + m_min_x); + m_cur_span->len = (coord_type)len; + m_cur_span->covers = &m_covers[x]; + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + x -= m_min_x; + std::memset(&m_covers[x], cover, len); + if(x == m_last_x+1) + { + m_cur_span->len += (coord_type)len; + } + else + { + m_cur_span++; + m_cur_span->x = (coord_type)(x + m_min_x); + m_cur_span->len = (coord_type)len; + m_cur_span->covers = &m_covers[x]; + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cur_span = &m_spans[0]; + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } + const_iterator begin() const { return &m_spans[1]; } + iterator begin() { return &m_spans[1]; } + + private: + scanline_u8(const self_type&); + const self_type& operator = (const self_type&); + + private: + int m_min_x; + int m_last_x; + int m_y; + pod_array<cover_type> m_covers; + pod_array<span> m_spans; + span* m_cur_span; + }; + + + + + //==========================================================scanline_u8_am + // + // The scanline container with alpha-masking + // + //------------------------------------------------------------------------ + template<class AlphaMask> + class scanline_u8_am : public scanline_u8 + { + public: + typedef scanline_u8 base_type; + typedef AlphaMask alpha_mask_type; + typedef base_type::cover_type cover_type; + typedef base_type::coord_type coord_type; + + scanline_u8_am() : base_type(), m_alpha_mask(0) {} + scanline_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {} + + //-------------------------------------------------------------------- + void finalize(int span_y) + { + base_type::finalize(span_y); + if(m_alpha_mask) + { + typename base_type::iterator span = base_type::begin(); + unsigned count = base_type::num_spans(); + do + { + m_alpha_mask->combine_hspan(span->x, + base_type::y(), + span->covers, + span->len); + ++span; + } + while(--count); + } + } + + private: + AlphaMask* m_alpha_mask; + }; + + + + + //===========================================================scanline32_u8 + class scanline32_u8 + { + public: + typedef scanline32_u8 self_type; + typedef int8u cover_type; + typedef int32 coord_type; + + //-------------------------------------------------------------------- + struct span + { + span() {} + span(coord_type x_, coord_type len_, cover_type* covers_) : + x(x_), len(len_), covers(covers_) {} + + coord_type x; + coord_type len; + cover_type* covers; + }; + + typedef pod_bvector<span, 4> span_array_type; + + //-------------------------------------------------------------------- + class const_iterator + { + public: + const_iterator(const span_array_type& spans) : + m_spans(spans), + m_span_idx(0) + {} + + const span& operator*() const { return m_spans[m_span_idx]; } + const span* operator->() const { return &m_spans[m_span_idx]; } + + void operator ++ () { ++m_span_idx; } + + private: + const span_array_type& m_spans; + unsigned m_span_idx; + }; + + //-------------------------------------------------------------------- + class iterator + { + public: + iterator(span_array_type& spans) : + m_spans(spans), + m_span_idx(0) + {} + + span& operator*() { return m_spans[m_span_idx]; } + span* operator->() { return &m_spans[m_span_idx]; } + + void operator ++ () { ++m_span_idx; } + + private: + span_array_type& m_spans; + unsigned m_span_idx; + }; + + + + //-------------------------------------------------------------------- + scanline32_u8() : + m_min_x(0), + m_last_x(0x7FFFFFF0), + m_covers() + {} + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 2; + if(max_len > m_covers.size()) + { + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_min_x = min_x; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover) + { + x -= m_min_x; + m_covers[x] = cover_type(cover); + if(x == m_last_x+1) + { + m_spans.last().len++; + } + else + { + m_spans.add(span(coord_type(x + m_min_x), 1, &m_covers[x])); + } + m_last_x = x; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const cover_type* covers) + { + x -= m_min_x; + std::memcpy(&m_covers[x], covers, len * sizeof(cover_type)); + if(x == m_last_x+1) + { + m_spans.last().len += coord_type(len); + } + else + { + m_spans.add(span(coord_type(x + m_min_x), + coord_type(len), + &m_covers[x])); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + x -= m_min_x; + std::memset(&m_covers[x], cover, len); + if(x == m_last_x+1) + { + m_spans.last().len += coord_type(len); + } + else + { + m_spans.add(span(coord_type(x + m_min_x), + coord_type(len), + &m_covers[x])); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return m_spans.size(); } + const_iterator begin() const { return const_iterator(m_spans); } + iterator begin() { return iterator(m_spans); } + + private: + scanline32_u8(const self_type&); + const self_type& operator = (const self_type&); + + private: + int m_min_x; + int m_last_x; + int m_y; + pod_array<cover_type> m_covers; + span_array_type m_spans; + }; + + + + + //========================================================scanline32_u8_am + // + // The scanline container with alpha-masking + // + //------------------------------------------------------------------------ + template<class AlphaMask> + class scanline32_u8_am : public scanline32_u8 + { + public: + typedef scanline32_u8 base_type; + typedef AlphaMask alpha_mask_type; + typedef base_type::cover_type cover_type; + typedef base_type::coord_type coord_type; + + + scanline32_u8_am() : base_type(), m_alpha_mask(0) {} + scanline32_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {} + + //-------------------------------------------------------------------- + void finalize(int span_y) + { + base_type::finalize(span_y); + if(m_alpha_mask) + { + typename base_type::iterator span = base_type::begin(); + unsigned count = base_type::num_spans(); + do + { + m_alpha_mask->combine_hspan(span->x, + base_type::y(), + span->covers, + span->len); + ++span; + } + while(--count); + } + } + + private: + AlphaMask* m_alpha_mask; + }; + + + +} + +#endif + diff --git a/include/agg_shorten_path.h b/include/agg_shorten_path.h new file mode 100644 index 0000000..dd9929f --- /dev/null +++ b/include/agg_shorten_path.h @@ -0,0 +1,66 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_SHORTEN_PATH_INCLUDED +#define AGG_SHORTEN_PATH_INCLUDED + +#include "agg_basics.h" +#include "agg_vertex_sequence.h" + +namespace agg +{ + + //===========================================================shorten_path + template<class VertexSequence> + void shorten_path(VertexSequence& vs, double s, unsigned closed = 0) + { + typedef typename VertexSequence::value_type vertex_type; + + if(s > 0.0 && vs.size() > 1) + { + double d; + int n = int(vs.size() - 2); + while(n) + { + d = vs[n].dist; + if(d > s) break; + vs.remove_last(); + s -= d; + --n; + } + if(vs.size() < 2) + { + vs.remove_all(); + } + else + { + n = vs.size() - 1; + vertex_type& prev = vs[n-1]; + vertex_type& last = vs[n]; + d = (prev.dist - s) / prev.dist; + double x = prev.x + (last.x - prev.x) * d; + double y = prev.y + (last.y - prev.y) * d; + last.x = x; + last.y = y; + if(!prev(last)) vs.remove_last(); + vs.close(closed != 0); + } + } + } + + +} + +#endif diff --git a/include/agg_simul_eq.h b/include/agg_simul_eq.h new file mode 100644 index 0000000..f7bfafd --- /dev/null +++ b/include/agg_simul_eq.h @@ -0,0 +1,147 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Solving simultaneous equations +// +//---------------------------------------------------------------------------- +#ifndef AGG_SIMUL_EQ_INCLUDED +#define AGG_SIMUL_EQ_INCLUDED + +#include <cmath> +#include "agg_basics.h" + +namespace agg +{ + + //=============================================================swap_arrays + template<class T> void swap_arrays(T* a1, T* a2, unsigned n) + { + unsigned i; + for(i = 0; i < n; i++) + { + T tmp = *a1; + *a1++ = *a2; + *a2++ = tmp; + } + } + + + //============================================================matrix_pivot + template<unsigned Rows, unsigned Cols> + struct matrix_pivot + { + static int pivot(double m[Rows][Cols], unsigned row) + { + int k = int(row); + double max_val, tmp; + + max_val = -1.0; + unsigned i; + for(i = row; i < Rows; i++) + { + if((tmp = std::fabs(m[i][row])) > max_val && tmp != 0.0) + { + max_val = tmp; + k = i; + } + } + + if(m[k][row] == 0.0) + { + return -1; + } + + if(k != int(row)) + { + swap_arrays(m[k], m[row], Cols); + return k; + } + return 0; + } + }; + + + + //===============================================================simul_eq + template<unsigned Size, unsigned RightCols> + struct simul_eq + { + static bool solve(const double left[Size][Size], + const double right[Size][RightCols], + double result[Size][RightCols]) + { + unsigned i, j, k; + double a1; + + double tmp[Size][Size + RightCols]; + + for(i = 0; i < Size; i++) + { + for(j = 0; j < Size; j++) + { + tmp[i][j] = left[i][j]; + } + for(j = 0; j < RightCols; j++) + { + tmp[i][Size + j] = right[i][j]; + } + } + + for(k = 0; k < Size; k++) + { + if(matrix_pivot<Size, Size + RightCols>::pivot(tmp, k) < 0) + { + return false; // Singularity.... + } + + a1 = tmp[k][k]; + + for(j = k; j < Size + RightCols; j++) + { + tmp[k][j] /= a1; + } + + for(i = k + 1; i < Size; i++) + { + a1 = tmp[i][k]; + for (j = k; j < Size + RightCols; j++) + { + tmp[i][j] -= a1 * tmp[k][j]; + } + } + } + + + for(k = 0; k < RightCols; k++) + { + int m; + for(m = int(Size - 1); m >= 0; m--) + { + result[m][k] = tmp[m][Size + k]; + for(j = m + 1; j < Size; j++) + { + result[m][k] -= tmp[m][j] * result[j][k]; + } + } + } + return true; + } + + }; + + +} + +#endif diff --git a/include/agg_span_allocator.h b/include/agg_span_allocator.h new file mode 100644 index 0000000..201b69b --- /dev/null +++ b/include/agg_span_allocator.h @@ -0,0 +1,54 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_ALLOCATOR_INCLUDED +#define AGG_SPAN_ALLOCATOR_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + //----------------------------------------------------------span_allocator + template<class ColorT> class span_allocator + { + public: + typedef ColorT color_type; + + //-------------------------------------------------------------------- + AGG_INLINE color_type* allocate(unsigned span_len) + { + if(span_len > m_span.size()) + { + // To reduce the number of reallocs we align the + // span_len to 256 color elements. + // Well, I just like this number and it looks reasonable. + //----------------------- + m_span.resize(((span_len + 255) >> 8) << 8); + } + return &m_span[0]; + } + + AGG_INLINE color_type* span() { return &m_span[0]; } + AGG_INLINE unsigned max_span_len() const { return m_span.size(); } + + private: + pod_array<color_type> m_span; + }; +} + + +#endif + + diff --git a/include/agg_span_converter.h b/include/agg_span_converter.h new file mode 100644 index 0000000..91d0f87 --- /dev/null +++ b/include/agg_span_converter.h @@ -0,0 +1,56 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_CONVERTER_INCLUDED +#define AGG_SPAN_CONVERTER_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //----------------------------------------------------------span_converter + template<class SpanGenerator, class SpanConverter> class span_converter + { + public: + typedef typename SpanGenerator::color_type color_type; + + span_converter(SpanGenerator& span_gen, SpanConverter& span_cnv) : + m_span_gen(&span_gen), m_span_cnv(&span_cnv) {} + + void attach_generator(SpanGenerator& span_gen) { m_span_gen = &span_gen; } + void attach_converter(SpanConverter& span_cnv) { m_span_cnv = &span_cnv; } + + //-------------------------------------------------------------------- + void prepare() + { + m_span_gen->prepare(); + m_span_cnv->prepare(); + } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + m_span_gen->generate(span, x, y, len); + m_span_cnv->generate(span, x, y, len); + } + + private: + SpanGenerator* m_span_gen; + SpanConverter* m_span_cnv; + }; + +} + +#endif diff --git a/include/agg_span_gouraud.h b/include/agg_span_gouraud.h new file mode 100644 index 0000000..2986c88 --- /dev/null +++ b/include/agg_span_gouraud.h @@ -0,0 +1,172 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_GOURAUD_INCLUDED +#define AGG_SPAN_GOURAUD_INCLUDED + +#include "agg_basics.h" +#include "agg_math.h" + +namespace agg +{ + + //============================================================span_gouraud + template<class ColorT> class span_gouraud + { + public: + typedef ColorT color_type; + + struct coord_type + { + double x; + double y; + color_type color; + }; + + //-------------------------------------------------------------------- + span_gouraud() : + m_vertex(0) + { + m_cmd[0] = path_cmd_stop; + } + + //-------------------------------------------------------------------- + span_gouraud(const color_type& c1, + const color_type& c2, + const color_type& c3, + double x1, double y1, + double x2, double y2, + double x3, double y3, + double d) : + m_vertex(0) + { + colors(c1, c2, c3); + triangle(x1, y1, x2, y2, x3, y3, d); + } + + //-------------------------------------------------------------------- + void colors(ColorT c1, ColorT c2, ColorT c3) + { + m_coord[0].color = c1; + m_coord[1].color = c2; + m_coord[2].color = c3; + } + + //-------------------------------------------------------------------- + // Sets the triangle and dilates it if needed. + // The trick here is to calculate beveled joins in the vertices of the + // triangle and render it as a 6-vertex polygon. + // It's necessary to achieve numerical stability. + // However, the coordinates to interpolate colors are calculated + // as miter joins (calc_intersection). + void triangle(double x1, double y1, + double x2, double y2, + double x3, double y3, + double d) + { + m_coord[0].x = m_x[0] = x1; + m_coord[0].y = m_y[0] = y1; + m_coord[1].x = m_x[1] = x2; + m_coord[1].y = m_y[1] = y2; + m_coord[2].x = m_x[2] = x3; + m_coord[2].y = m_y[2] = y3; + m_cmd[0] = path_cmd_move_to; + m_cmd[1] = path_cmd_line_to; + m_cmd[2] = path_cmd_line_to; + m_cmd[3] = path_cmd_stop; + + if(d != 0.0) + { + dilate_triangle(m_coord[0].x, m_coord[0].y, + m_coord[1].x, m_coord[1].y, + m_coord[2].x, m_coord[2].y, + m_x, m_y, d); + + calc_intersection(m_x[4], m_y[4], m_x[5], m_y[5], + m_x[0], m_y[0], m_x[1], m_y[1], + &m_coord[0].x, &m_coord[0].y); + + calc_intersection(m_x[0], m_y[0], m_x[1], m_y[1], + m_x[2], m_y[2], m_x[3], m_y[3], + &m_coord[1].x, &m_coord[1].y); + + calc_intersection(m_x[2], m_y[2], m_x[3], m_y[3], + m_x[4], m_y[4], m_x[5], m_y[5], + &m_coord[2].x, &m_coord[2].y); + m_cmd[3] = path_cmd_line_to; + m_cmd[4] = path_cmd_line_to; + m_cmd[5] = path_cmd_line_to; + m_cmd[6] = path_cmd_stop; + } + } + + //-------------------------------------------------------------------- + // Vertex Source Interface to feed the coordinates to the rasterizer + void rewind(unsigned) + { + m_vertex = 0; + } + + //-------------------------------------------------------------------- + unsigned vertex(double* x, double* y) + { + *x = m_x[m_vertex]; + *y = m_y[m_vertex]; + return m_cmd[m_vertex++]; + } + + protected: + //-------------------------------------------------------------------- + void arrange_vertices(coord_type* coord) const + { + coord[0] = m_coord[0]; + coord[1] = m_coord[1]; + coord[2] = m_coord[2]; + + if(m_coord[0].y > m_coord[2].y) + { + coord[0] = m_coord[2]; + coord[2] = m_coord[0]; + } + + coord_type tmp; + if(coord[0].y > coord[1].y) + { + tmp = coord[1]; + coord[1] = coord[0]; + coord[0] = tmp; + } + + if(coord[1].y > coord[2].y) + { + tmp = coord[2]; + coord[2] = coord[1]; + coord[1] = tmp; + } + } + + private: + //-------------------------------------------------------------------- + coord_type m_coord[3]; + double m_x[8]; + double m_y[8]; + unsigned m_cmd[8]; + unsigned m_vertex; + }; + +} + +#endif + diff --git a/include/agg_span_gouraud_gray.h b/include/agg_span_gouraud_gray.h new file mode 100644 index 0000000..aa73e5b --- /dev/null +++ b/include/agg_span_gouraud_gray.h @@ -0,0 +1,243 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_GOURAUD_GRAY_INCLUDED +#define AGG_SPAN_GOURAUD_GRAY_INCLUDED + +#include <cmath> +#include <cstdlib> +#include "agg_basics.h" +#include "agg_color_gray.h" +#include "agg_dda_line.h" +#include "agg_span_gouraud.h" + +namespace agg +{ + + //=======================================================span_gouraud_gray + template<class ColorT> class span_gouraud_gray : public span_gouraud<ColorT> + { + public: + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + typedef span_gouraud<color_type> base_type; + typedef typename base_type::coord_type coord_type; + enum subpixel_scale_e + { + subpixel_shift = 4, + subpixel_scale = 1 << subpixel_shift + }; + + private: + //-------------------------------------------------------------------- + struct gray_calc + { + void init(const coord_type& c1, const coord_type& c2) + { + m_x1 = c1.x - 0.5; + m_y1 = c1.y - 0.5; + m_dx = c2.x - c1.x; + double dy = c2.y - c1.y; + m_1dy = (std::fabs(dy) < 1e-10) ? 1e10 : 1.0 / dy; + m_v1 = c1.color.v; + m_a1 = c1.color.a; + m_dv = c2.color.v - m_v1; + m_da = c2.color.a - m_a1; + } + + void calc(double y) + { + double k = (y - m_y1) * m_1dy; + if(k < 0.0) k = 0.0; + if(k > 1.0) k = 1.0; + m_v = m_v1 + iround(m_dv * k); + m_a = m_a1 + iround(m_da * k); + m_x = iround((m_x1 + m_dx * k) * subpixel_scale); + } + + double m_x1; + double m_y1; + double m_dx; + double m_1dy; + int m_v1; + int m_a1; + int m_dv; + int m_da; + int m_v; + int m_a; + int m_x; + }; + + + public: + //-------------------------------------------------------------------- + span_gouraud_gray() {} + span_gouraud_gray(const color_type& c1, + const color_type& c2, + const color_type& c3, + double x1, double y1, + double x2, double y2, + double x3, double y3, + double d = 0) : + base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d) + {} + + //-------------------------------------------------------------------- + void prepare() + { + coord_type coord[3]; + base_type::arrange_vertices(coord); + + m_y2 = int(coord[1].y); + + m_swap = cross_product(coord[0].x, coord[0].y, + coord[2].x, coord[2].y, + coord[1].x, coord[1].y) < 0.0; + + m_c1.init(coord[0], coord[2]); + m_c2.init(coord[0], coord[1]); + m_c3.init(coord[1], coord[2]); + } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + m_c1.calc(y); + const gray_calc* pc1 = &m_c1; + const gray_calc* pc2 = &m_c2; + + if(y < m_y2) + { + // Bottom part of the triangle (first subtriangle) + //------------------------- + m_c2.calc(y + m_c2.m_1dy); + } + else + { + // Upper part (second subtriangle) + //------------------------- + m_c3.calc(y - m_c3.m_1dy); + pc2 = &m_c3; + } + + if(m_swap) + { + // It means that the triangle is oriented clockwise, + // so that we need to swap the controlling structures + //------------------------- + const gray_calc* t = pc2; + pc2 = pc1; + pc1 = t; + } + + // Get the horizontal length with subpixel accuracy + // and protect it from division by zero + //------------------------- + int nlen = std::abs(pc2->m_x - pc1->m_x); + if(nlen <= 0) nlen = 1; + + dda_line_interpolator<14> v(pc1->m_v, pc2->m_v, nlen); + dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen); + + // Calculate the starting point of the gradient with subpixel + // accuracy and correct (roll back) the interpolators. + // This operation will also clip the beginning of the span + // if necessary. + //------------------------- + int start = pc1->m_x - (x << subpixel_shift); + v -= start; + a -= start; + nlen += start; + + int vv, va; + enum lim_e { lim = color_type::base_mask }; + + // Beginning part of the span. Since we rolled back the + // interpolators, the color values may have overflow. + // So that, we render the beginning part with checking + // for overflow. It lasts until "start" is positive; + // typically it's 1-2 pixels, but may be more in some cases. + //------------------------- + while(len && start > 0) + { + vv = v.y(); + va = a.y(); + if(vv < 0) vv = 0; if(vv > lim) vv = lim; + if(va < 0) va = 0; if(va > lim) va = lim; + span->v = (value_type)vv; + span->a = (value_type)va; + v += subpixel_scale; + a += subpixel_scale; + nlen -= subpixel_scale; + start -= subpixel_scale; + ++span; + --len; + } + + // Middle part, no checking for overflow. + // Actual spans can be longer than the calculated length + // because of anti-aliasing, thus, the interpolators can + // overflow. But while "nlen" is positive we are safe. + //------------------------- + while(len && nlen > 0) + { + span->v = (value_type)v.y(); + span->a = (value_type)a.y(); + v += subpixel_scale; + a += subpixel_scale; + nlen -= subpixel_scale; + ++span; + --len; + } + + // Ending part; checking for overflow. + // Typically it's 1-2 pixels, but may be more in some cases. + //------------------------- + while(len) + { + vv = v.y(); + va = a.y(); + if(vv < 0) vv = 0; if(vv > lim) vv = lim; + if(va < 0) va = 0; if(va > lim) va = lim; + span->v = (value_type)vv; + span->a = (value_type)va; + v += subpixel_scale; + a += subpixel_scale; + ++span; + --len; + } + } + + + private: + bool m_swap; + int m_y2; + gray_calc m_c1; + gray_calc m_c2; + gray_calc m_c3; + }; + + +} + +#endif diff --git a/include/agg_span_gouraud_rgba.h b/include/agg_span_gouraud_rgba.h new file mode 100644 index 0000000..887a334 --- /dev/null +++ b/include/agg_span_gouraud_rgba.h @@ -0,0 +1,278 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_GOURAUD_RGBA_INCLUDED +#define AGG_SPAN_GOURAUD_RGBA_INCLUDED + +#include <cstdlib> +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_dda_line.h" +#include "agg_span_gouraud.h" + +namespace agg +{ + + //=======================================================span_gouraud_rgba + template<class ColorT> class span_gouraud_rgba : public span_gouraud<ColorT> + { + public: + typedef ColorT color_type; + typedef typename ColorT::value_type value_type; + typedef span_gouraud<color_type> base_type; + typedef typename base_type::coord_type coord_type; + enum subpixel_scale_e + { + subpixel_shift = 4, + subpixel_scale = 1 << subpixel_shift + }; + + private: + //-------------------------------------------------------------------- + struct rgba_calc + { + void init(const coord_type& c1, const coord_type& c2) + { + m_x1 = c1.x - 0.5; + m_y1 = c1.y - 0.5; + m_dx = c2.x - c1.x; + double dy = c2.y - c1.y; + m_1dy = (dy < 1e-5) ? 1e5 : 1.0 / dy; + m_r1 = c1.color.r; + m_g1 = c1.color.g; + m_b1 = c1.color.b; + m_a1 = c1.color.a; + m_dr = c2.color.r - m_r1; + m_dg = c2.color.g - m_g1; + m_db = c2.color.b - m_b1; + m_da = c2.color.a - m_a1; + } + + void calc(double y) + { + double k = (y - m_y1) * m_1dy; + if(k < 0.0) k = 0.0; + if(k > 1.0) k = 1.0; + m_r = m_r1 + iround(m_dr * k); + m_g = m_g1 + iround(m_dg * k); + m_b = m_b1 + iround(m_db * k); + m_a = m_a1 + iround(m_da * k); + m_x = iround((m_x1 + m_dx * k) * subpixel_scale); + } + + double m_x1; + double m_y1; + double m_dx; + double m_1dy; + int m_r1; + int m_g1; + int m_b1; + int m_a1; + int m_dr; + int m_dg; + int m_db; + int m_da; + int m_r; + int m_g; + int m_b; + int m_a; + int m_x; + }; + + public: + + //-------------------------------------------------------------------- + span_gouraud_rgba() {} + span_gouraud_rgba(const color_type& c1, + const color_type& c2, + const color_type& c3, + double x1, double y1, + double x2, double y2, + double x3, double y3, + double d = 0) : + base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d) + {} + + //-------------------------------------------------------------------- + void prepare() + { + coord_type coord[3]; + base_type::arrange_vertices(coord); + + m_y2 = int(coord[1].y); + + m_swap = cross_product(coord[0].x, coord[0].y, + coord[2].x, coord[2].y, + coord[1].x, coord[1].y) < 0.0; + + m_rgba1.init(coord[0], coord[2]); + m_rgba2.init(coord[0], coord[1]); + m_rgba3.init(coord[1], coord[2]); + } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + m_rgba1.calc(y);//(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y); + const rgba_calc* pc1 = &m_rgba1; + const rgba_calc* pc2 = &m_rgba2; + + if(y <= m_y2) + { + // Bottom part of the triangle (first subtriangle) + //------------------------- + m_rgba2.calc(y + m_rgba2.m_1dy); + } + else + { + // Upper part (second subtriangle) + m_rgba3.calc(y - m_rgba3.m_1dy); + //------------------------- + pc2 = &m_rgba3; + } + + if(m_swap) + { + // It means that the triangle is oriented clockwise, + // so that we need to swap the controlling structures + //------------------------- + const rgba_calc* t = pc2; + pc2 = pc1; + pc1 = t; + } + + // Get the horizontal length with subpixel accuracy + // and protect it from division by zero + //------------------------- + int nlen = std::abs(pc2->m_x - pc1->m_x); + if(nlen <= 0) nlen = 1; + + dda_line_interpolator<14> r(pc1->m_r, pc2->m_r, nlen); + dda_line_interpolator<14> g(pc1->m_g, pc2->m_g, nlen); + dda_line_interpolator<14> b(pc1->m_b, pc2->m_b, nlen); + dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen); + + // Calculate the starting point of the gradient with subpixel + // accuracy and correct (roll back) the interpolators. + // This operation will also clip the beginning of the span + // if necessary. + //------------------------- + int start = pc1->m_x - (x << subpixel_shift); + r -= start; + g -= start; + b -= start; + a -= start; + nlen += start; + + int vr, vg, vb, va; + enum lim_e { lim = color_type::base_mask }; + + // Beginning part of the span. Since we rolled back the + // interpolators, the color values may have overflow. + // So that, we render the beginning part with checking + // for overflow. It lasts until "start" is positive; + // typically it's 1-2 pixels, but may be more in some cases. + //------------------------- + while(len && start > 0) + { + vr = r.y(); + vg = g.y(); + vb = b.y(); + va = a.y(); + if(vr < 0) { vr = 0; } if(vr > lim) { vr = lim; } + if(vg < 0) { vg = 0; } if(vg > lim) { vg = lim; } + if(vb < 0) { vb = 0; } if(vb > lim) { vb = lim; } + if(va < 0) { va = 0; } if(va > lim) { va = lim; } + span->r = (value_type)vr; + span->g = (value_type)vg; + span->b = (value_type)vb; + span->a = (value_type)va; + r += subpixel_scale; + g += subpixel_scale; + b += subpixel_scale; + a += subpixel_scale; + nlen -= subpixel_scale; + start -= subpixel_scale; + ++span; + --len; + } + + // Middle part, no checking for overflow. + // Actual spans can be longer than the calculated length + // because of anti-aliasing, thus, the interpolators can + // overflow. But while "nlen" is positive we are safe. + //------------------------- + while(len && nlen > 0) + { + span->r = (value_type)r.y(); + span->g = (value_type)g.y(); + span->b = (value_type)b.y(); + span->a = (value_type)a.y(); + r += subpixel_scale; + g += subpixel_scale; + b += subpixel_scale; + a += subpixel_scale; + nlen -= subpixel_scale; + ++span; + --len; + } + + // Ending part; checking for overflow. + // Typically it's 1-2 pixels, but may be more in some cases. + //------------------------- + while(len) + { + vr = r.y(); + vg = g.y(); + vb = b.y(); + va = a.y(); + if(vr < 0) { vr = 0; } if(vr > lim) { vr = lim; } + if(vg < 0) { vg = 0; } if(vg > lim) { vg = lim; } + if(vb < 0) { vb = 0; } if(vb > lim) { vb = lim; } + if(va < 0) { va = 0; } if(va > lim) { va = lim; } + span->r = (value_type)vr; + span->g = (value_type)vg; + span->b = (value_type)vb; + span->a = (value_type)va; + r += subpixel_scale; + g += subpixel_scale; + b += subpixel_scale; + a += subpixel_scale; + ++span; + --len; + } + } + + private: + bool m_swap; + int m_y2; + rgba_calc m_rgba1; + rgba_calc m_rgba2; + rgba_calc m_rgba3; + }; + + + +} + +#endif diff --git a/include/agg_span_gradient.h b/include/agg_span_gradient.h new file mode 100644 index 0000000..8cedbda --- /dev/null +++ b/include/agg_span_gradient.h @@ -0,0 +1,376 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_GRADIENT_INCLUDED +#define AGG_SPAN_GRADIENT_INCLUDED + +#include <cmath> +#include <cstdlib> +#include "agg_basics.h" +#include "agg_math.h" +#include "agg_array.h" + + +namespace agg +{ + + enum gradient_subpixel_scale_e + { + gradient_subpixel_shift = 4, //-----gradient_subpixel_shift + gradient_subpixel_scale = 1 << gradient_subpixel_shift, //-----gradient_subpixel_scale + gradient_subpixel_mask = gradient_subpixel_scale - 1 //-----gradient_subpixel_mask + }; + + + + //==========================================================span_gradient + template<class ColorT, + class Interpolator, + class GradientF, + class ColorF> + class span_gradient + { + public: + typedef Interpolator interpolator_type; + typedef ColorT color_type; + + enum downscale_shift_e + { + downscale_shift = interpolator_type::subpixel_shift - + gradient_subpixel_shift + }; + + //-------------------------------------------------------------------- + span_gradient() {} + + //-------------------------------------------------------------------- + span_gradient(interpolator_type& inter, + GradientF& gradient_function, + ColorF& color_function, + double d1, double d2) : + m_interpolator(&inter), + m_gradient_function(&gradient_function), + m_color_function(&color_function), + m_d1(iround(d1 * gradient_subpixel_scale)), + m_d2(iround(d2 * gradient_subpixel_scale)) + {} + + //-------------------------------------------------------------------- + interpolator_type& interpolator() { return *m_interpolator; } + const GradientF& gradient_function() const { return *m_gradient_function; } + const ColorF& color_function() const { return *m_color_function; } + double d1() const { return double(m_d1) / gradient_subpixel_scale; } + double d2() const { return double(m_d2) / gradient_subpixel_scale; } + + //-------------------------------------------------------------------- + void interpolator(interpolator_type& i) { m_interpolator = &i; } + void gradient_function(GradientF& gf) { m_gradient_function = &gf; } + void color_function(ColorF& cf) { m_color_function = &cf; } + void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); } + void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + int dd = m_d2 - m_d1; + if(dd < 1) dd = 1; + m_interpolator->begin(x+0.5, y+0.5, len); + do + { + m_interpolator->coordinates(&x, &y); + int d = m_gradient_function->calculate(x >> downscale_shift, + y >> downscale_shift, m_d2); + d = ((d - m_d1) * (int)m_color_function->size()) / dd; + if(d < 0) d = 0; + if(d >= (int)m_color_function->size()) d = m_color_function->size() - 1; + *span++ = (*m_color_function)[d]; + ++(*m_interpolator); + } + while(--len); + } + + private: + interpolator_type* m_interpolator; + GradientF* m_gradient_function; + ColorF* m_color_function; + int m_d1; + int m_d2; + }; + + + + + //=====================================================gradient_linear_color + template<class ColorT> + struct gradient_linear_color + { + typedef ColorT color_type; + + gradient_linear_color() {} + gradient_linear_color(const color_type& c1, const color_type& c2, + unsigned size = 256) : + m_c1(c1), m_c2(c2), m_size(size) + // VFALCO 4/28/09 + ,m_mult(1/(double(size)-1)) + // VFALCO + {} + + unsigned size() const { return m_size; } + color_type operator [] (unsigned v) const + { + // VFALCO 4/28/09 + //return m_c1.gradient(m_c2, double(v) / double(m_size - 1)); + return m_c1.gradient(m_c2, double(v) * m_mult ); + // VFALCO + } + + void colors(const color_type& c1, const color_type& c2, unsigned size = 256) + { + m_c1 = c1; + m_c2 = c2; + m_size = size; + // VFALCO 4/28/09 + m_mult=1/(double(size)-1); + // VFALCO + } + + color_type m_c1; + color_type m_c2; + unsigned m_size; + // VFALCO 4/28/09 + double m_mult; + // VFALCO + }; + + + + + + + //==========================================================gradient_circle + class gradient_circle + { + // Actually the same as radial. Just for compatibility + public: + static AGG_INLINE int calculate(int x, int y, int) + { + return int(fast_sqrt(x*x + y*y)); + } + }; + + + //==========================================================gradient_radial + class gradient_radial + { + public: + static AGG_INLINE int calculate(int x, int y, int) + { + return int(fast_sqrt(x*x + y*y)); + } + }; + + //========================================================gradient_radial_d + class gradient_radial_d + { + public: + static AGG_INLINE int calculate(int x, int y, int) + { + return uround(std::sqrt(double(x)*double(x) + double(y)*double(y))); + } + }; + + //====================================================gradient_radial_focus + class gradient_radial_focus + { + public: + //--------------------------------------------------------------------- + gradient_radial_focus() : + m_r(100 * gradient_subpixel_scale), + m_fx(0), + m_fy(0) + { + update_values(); + } + + //--------------------------------------------------------------------- + gradient_radial_focus(double r, double fx, double fy) : + m_r (iround(r * gradient_subpixel_scale)), + m_fx(iround(fx * gradient_subpixel_scale)), + m_fy(iround(fy * gradient_subpixel_scale)) + { + update_values(); + } + + //--------------------------------------------------------------------- + void init(double r, double fx, double fy) + { + m_r = iround(r * gradient_subpixel_scale); + m_fx = iround(fx * gradient_subpixel_scale); + m_fy = iround(fy * gradient_subpixel_scale); + update_values(); + } + + //--------------------------------------------------------------------- + double radius() const { return double(m_r) / gradient_subpixel_scale; } + double focus_x() const { return double(m_fx) / gradient_subpixel_scale; } + double focus_y() const { return double(m_fy) / gradient_subpixel_scale; } + + //--------------------------------------------------------------------- + int calculate(int x, int y, int) const + { + double dx = x - m_fx; + double dy = y - m_fy; + double d2 = dx * m_fy - dy * m_fx; + double d3 = m_r2 * (dx * dx + dy * dy) - d2 * d2; + return iround((dx * m_fx + dy * m_fy + std::sqrt(std::fabs(d3))) * m_mul); + } + + private: + //--------------------------------------------------------------------- + void update_values() + { + // Calculate the invariant values. In case the focal center + // lies exactly on the gradient circle the divisor degenerates + // into zero. In this case we just move the focal center by + // one subpixel unit possibly in the direction to the origin (0,0) + // and calculate the values again. + //------------------------- + m_r2 = double(m_r) * double(m_r); + m_fx2 = double(m_fx) * double(m_fx); + m_fy2 = double(m_fy) * double(m_fy); + double d = (m_r2 - (m_fx2 + m_fy2)); + if(d == 0) + { + if(m_fx) { if(m_fx < 0) ++m_fx; else --m_fx; } + if(m_fy) { if(m_fy < 0) ++m_fy; else --m_fy; } + m_fx2 = double(m_fx) * double(m_fx); + m_fy2 = double(m_fy) * double(m_fy); + d = (m_r2 - (m_fx2 + m_fy2)); + } + m_mul = m_r / d; + } + + int m_r; + int m_fx; + int m_fy; + double m_r2; + double m_fx2; + double m_fy2; + double m_mul; + }; + + + //==============================================================gradient_x + class gradient_x + { + public: + static int calculate(int x, int, int) { return x; } + }; + + + //==============================================================gradient_y + class gradient_y + { + public: + static int calculate(int, int y, int) { return y; } + }; + + //========================================================gradient_diamond + class gradient_diamond + { + public: + static AGG_INLINE int calculate(int x, int y, int) + { + int ax = std::abs(x); + int ay = std::abs(y); + return ax > ay ? ax : ay; + } + }; + + //=============================================================gradient_xy + class gradient_xy + { + public: + static AGG_INLINE int calculate(int x, int y, int d) + { + return std::abs(x) * std::abs(y) / d; + } + }; + + //========================================================gradient_sqrt_xy + class gradient_sqrt_xy + { + public: + static AGG_INLINE int calculate(int x, int y, int) + { + return fast_sqrt(std::abs(x) * std::abs(y)); + } + }; + + //==========================================================gradient_conic + class gradient_conic + { + public: + static AGG_INLINE int calculate(int x, int y, int d) + { + return uround(std::fabs(std::atan2(double(y), double(x))) * double(d) / pi); + } + }; + + //=================================================gradient_repeat_adaptor + template<class GradientF> class gradient_repeat_adaptor + { + public: + gradient_repeat_adaptor(const GradientF& gradient) : + m_gradient(&gradient) {} + + AGG_INLINE int calculate(int x, int y, int d) const + { + int ret = m_gradient->calculate(x, y, d) % d; + if(ret < 0) ret += d; + return ret; + } + + private: + const GradientF* m_gradient; + }; + + //================================================gradient_reflect_adaptor + template<class GradientF> class gradient_reflect_adaptor + { + public: + gradient_reflect_adaptor(const GradientF& gradient) : + m_gradient(&gradient) {} + + AGG_INLINE int calculate(int x, int y, int d) const + { + int d2 = d << 1; + int ret = m_gradient->calculate(x, y, d) % d2; + if(ret < 0) ret += d2; + if(ret >= d) ret = d2 - ret; + return ret; + } + + private: + const GradientF* m_gradient; + }; + + +} + +#endif diff --git a/include/agg_span_gradient_alpha.h b/include/agg_span_gradient_alpha.h new file mode 100644 index 0000000..2ec040e --- /dev/null +++ b/include/agg_span_gradient_alpha.h @@ -0,0 +1,126 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_GRADIENT_ALPHA_INCLUDED +#define AGG_SPAN_GRADIENT_ALPHA_INCLUDED + +#include "agg_span_gradient.h" + +namespace agg +{ + //======================================================span_gradient_alpha + template<class ColorT, + class Interpolator, + class GradientF, + class AlphaF> + class span_gradient_alpha + { + public: + typedef Interpolator interpolator_type; + typedef ColorT color_type; + typedef typename color_type::value_type alpha_type; + + enum downscale_shift_e + { + downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift + }; + + + //-------------------------------------------------------------------- + span_gradient_alpha() {} + + //-------------------------------------------------------------------- + span_gradient_alpha(interpolator_type& inter, + GradientF& gradient_function, + AlphaF& alpha_function, + double d1, double d2) : + m_interpolator(&inter), + m_gradient_function(&gradient_function), + m_alpha_function(&alpha_function), + m_d1(iround(d1 * gradient_subpixel_scale)), + m_d2(iround(d2 * gradient_subpixel_scale)) + {} + + //-------------------------------------------------------------------- + interpolator_type& interpolator() { return *m_interpolator; } + const GradientF& gradient_function() const { return *m_gradient_function; } + const AlphaF& alpha_function() const { return *m_alpha_function; } + double d1() const { return double(m_d1) / gradient_subpixel_scale; } + double d2() const { return double(m_d2) / gradient_subpixel_scale; } + + //-------------------------------------------------------------------- + void interpolator(interpolator_type& i) { m_interpolator = &i; } + void gradient_function(const GradientF& gf) { m_gradient_function = &gf; } + void alpha_function(const AlphaF& af) { m_alpha_function = ⁡ } + void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); } + void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + int dd = m_d2 - m_d1; + if(dd < 1) dd = 1; + m_interpolator->begin(x+0.5, y+0.5, len); + do + { + m_interpolator->coordinates(&x, &y); + int d = m_gradient_function->calculate(x >> downscale_shift, + y >> downscale_shift, m_d2); + d = ((d - m_d1) * (int)m_alpha_function->size()) / dd; + if(d < 0) d = 0; + if(d >= (int)m_alpha_function->size()) d = m_alpha_function->size() - 1; + span->a = (*m_alpha_function)[d]; + ++span; + ++(*m_interpolator); + } + while(--len); + } + + private: + interpolator_type* m_interpolator; + GradientF* m_gradient_function; + AlphaF* m_alpha_function; + int m_d1; + int m_d2; + }; + + + //=======================================================gradient_alpha_x + template<class ColorT> struct gradient_alpha_x + { + typedef typename ColorT::value_type alpha_type; + alpha_type operator [] (alpha_type x) const { return x; } + }; + + //====================================================gradient_alpha_x_u8 + struct gradient_alpha_x_u8 + { + typedef int8u alpha_type; + alpha_type operator [] (alpha_type x) const { return x; } + }; + + //==========================================gradient_alpha_one_munus_x_u8 + struct gradient_alpha_one_munus_x_u8 + { + typedef int8u alpha_type; + alpha_type operator [] (alpha_type x) const { return 255-x; } + }; + +} + +#endif diff --git a/include/agg_span_gradient_contour.h b/include/agg_span_gradient_contour.h new file mode 100644 index 0000000..4b86817 --- /dev/null +++ b/include/agg_span_gradient_contour.h @@ -0,0 +1,364 @@ +//---------------------------------------------------------------------------- +// 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 +// +// 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. +// +// [History] ----------------------------------------------------------------- +// +// 02.02.2008-Milano: Ported from Object Pascal code of AggPas +// +#ifndef AGG_SPAN_GRADIENT_CONTOUR_INCLUDED +#define AGG_SPAN_GRADIENT_CONTOUR_INCLUDED + +#include "agg_basics.h" +#include "agg_trans_affine.h" +#include "agg_path_storage.h" +#include "agg_pixfmt_gray.h" +#include "agg_conv_transform.h" +#include "agg_conv_curve.h" +#include "agg_bounding_rect.h" +#include "agg_renderer_base.h" +#include "agg_renderer_primitives.h" +#include "agg_rasterizer_outline.h" +#include "agg_span_gradient.h" + +#include <cfloat> +#include <cmath> +#include <cstring> + +namespace agg +{ + + //==========================================================gradient_contour + class gradient_contour + { + private: + int8u* m_buffer; + int m_width; + int m_height; + int m_frame; + + double m_d1; + double m_d2; + + public: + gradient_contour() : + m_buffer(NULL), + m_width(0), + m_height(0), + m_frame(10), + m_d1(0), + m_d2(100) + { + } + + gradient_contour(double d1, double d2) : + m_buffer(NULL), + m_width(0), + m_height(0), + m_frame(10), + m_d1(d1), + m_d2(d2) + { + } + + ~gradient_contour() + { + if (m_buffer) + { + delete [] m_buffer; + } + } + + int8u* contour_create(path_storage* ps ); + + int contour_width() { return m_width; } + int contour_height() { return m_height; } + + void d1(double d ) { m_d1 = d; } + void d2(double d ) { m_d2 = d; } + + void frame(int f ) { m_frame = f; } + int frame() { return m_frame; } + + int calculate(int x, int y, int d) const + { + if (m_buffer) + { + int px = x >> agg::gradient_subpixel_shift; + int py = y >> agg::gradient_subpixel_shift; + + px %= m_width; + + if (px < 0) + { + px += m_width; + } + + py %= m_height; + + if (py < 0 ) + { + py += m_height; + } + + return iround(m_buffer[py * m_width + px ] * (m_d2 / 256 ) + m_d1 ) << gradient_subpixel_shift; + + } + else + { + return 0; + } + } + + }; + + static AGG_INLINE int square(int x ) { return x * x; } + + // DT algorithm by: Pedro Felzenszwalb + void dt(float* spanf, float* spang, float* spanr, int* spann ,int length ) + { + int k = 0; + float s; + + spann[0 ] = 0; + spang[0 ] = -FLT_MAX; + spang[1 ] = FLT_MAX; + + for (int q = 1; q <= length - 1; q++) + { + s = ((spanf[q ] + square(q ) ) - (spanf[spann[k ] ] + square(spann[k ] ) ) ) / (2 * q - 2 * spann[k ] ); + + while (s <= spang[k ]) + { + k--; + s = ((spanf[q ] + square(q ) ) - (spanf[spann[k ] ] + square(spann[k ] ) ) ) / (2 * q - 2 * spann[k ] ); + } + + k++; + spann[k ] = q; + spang[k ] = s; + spang[k + 1 ] = FLT_MAX; + + } + + k = 0; + + for (int q = 0; q <= length - 1; q++) + { + while (spang[k + 1 ] < q ) + { + k++; + } + + spanr[q ] = square(q - spann[k ] ) + spanf[spann[k ] ]; + } + } + + // DT algorithm by: Pedro Felzenszwalb + int8u* gradient_contour::contour_create(path_storage* ps ) + { + int8u* result = NULL; + + if (ps) + { + // I. Render Black And White NonAA Stroke of the Path + // Path Bounding Box + Some Frame Space Around [configurable] + agg::conv_curve<agg::path_storage> conv(*ps); + + double x1, y1, x2, y2; + + if (agg::bounding_rect_single(conv ,0 ,&x1 ,&y1 ,&x2 ,&y2 )) + { + // Create BW Rendering Surface + int width = int(ceil(x2 - x1 ) ) + m_frame * 2 + 1; + int height = int(ceil(y2 - y1 ) ) + m_frame * 2 + 1; + + int8u* buffer = new int8u[width * height]; + + if (buffer) + { + std::memset(buffer ,255 ,width * height ); + + // Setup VG Engine & Render + agg::rendering_buffer rb; + rb.attach(buffer ,width ,height ,width ); + + agg::pixfmt_gray8 pf(rb); + agg::renderer_base<agg::pixfmt_gray8> renb(pf ); + + agg::renderer_primitives<agg::renderer_base<agg::pixfmt_gray8> > prim(renb ); + agg::rasterizer_outline<renderer_primitives<agg::renderer_base<agg::pixfmt_gray8> > > ras(prim ); + + agg::trans_affine mtx; + mtx *= agg::trans_affine_translation(-x1 + m_frame, -y1 + m_frame ); + + agg::conv_transform<agg::conv_curve<agg::path_storage> > trans(conv ,mtx ); + + prim.line_color(agg::rgba8(0 ,0 ,0 ,255 ) ); + ras.add_path(trans ); + + // II. Distance Transform + // Create Float Buffer + 0 vs infinity assignment + float* image = new float[width * height]; + + if (image) + { + for (int y = 0, l = 0; y < height; y++ ) + { + for (int x = 0; x < width; x++, l++ ) + { + if (buffer[l ] == 0) + { + image[l ] = 0.0; + } + else + { + image[l ] = FLT_MAX; + } + } + + } + + // DT of 2d + // SubBuff<float> max width,height + int length = width; + + if (height > length) + { + length = height; + } + + float* spanf = new float[length]; + float* spang = new float[length + 1]; + float* spanr = new float[length]; + int* spann = new int[length]; + + if ((spanf) && (spang) && (spanr) && (spann)) + { + // Transform along columns + for (int x = 0; x < width; x++ ) + { + for (int y = 0; y < height; y++ ) + { + spanf[y] = image[y * width + x]; + } + + // DT of 1d + dt(spanf ,spang ,spanr ,spann ,height ); + + for (int y = 0; y < height; y++ ) + { + image[y * width + x] = spanr[y]; + } + } + + // Transform along rows + for (int y = 0; y < height; y++ ) + { + for (int x = 0; x < width; x++ ) + { + spanf[x] = image[y * width + x]; + } + + // DT of 1d + dt(spanf ,spang ,spanr ,spann ,width ); + + for (int x = 0; x < width; x++ ) + { + image[y * width + x] = spanr[x]; + } + } + + // Take Square Roots, Min & Max + float min = std::sqrt(image[0] ); + float max = min; + + for (int y = 0, l = 0; y < height; y++ ) + { + for (int x = 0; x < width; x++, l++ ) + { + image[l] = std::sqrt(image[l]); + + if (min > image[l]) + { + min = image[l]; + } + + if (max < image[l]) + { + max = image[l]; + } + + } + } + + // III. Convert To Grayscale + if (min == max) + { + std::memset(buffer ,0 ,width * height ); + } + else + { + float scale = 255 / (max - min ); + + for (int y = 0, l = 0; y < height; y++ ) + { + for (int x = 0; x < width; x++ ,l++ ) + { + buffer[l] = int8u(int((image[l] - min ) * scale )); + } + } + } + + // OK + if (m_buffer) + { + delete [] m_buffer; + } + + m_buffer = buffer; + m_width = width; + m_height = height; + + buffer = NULL; + result = m_buffer; + + } + + if (spanf) { delete [] spanf; } + if (spang) { delete [] spang; } + if (spanr) { delete [] spanr; } + if (spann) { delete [] spann; } + + delete [] image; + + } + } + + if (buffer) + { + delete [] buffer; + } + + } + + } + return result; + } + +} + +#endif diff --git a/include/agg_span_gradient_image.h b/include/agg_span_gradient_image.h new file mode 100644 index 0000000..20a442d --- /dev/null +++ b/include/agg_span_gradient_image.h @@ -0,0 +1,189 @@ +//---------------------------------------------------------------------------- +// 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 +// +// 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. +// +// [History] ----------------------------------------------------------------- +// +// 03.02.2008-Milano: Ported from Object Pascal code of AggPas +// +#ifndef AGG_SPAN_GRADIENT_IMAGE_INCLUDED +#define AGG_SPAN_GRADIENT_IMAGE_INCLUDED + +#include <cstring> +#include "agg_basics.h" +#include "agg_span_gradient.h" +#include "agg_color_rgba.h" +#include "agg_rendering_buffer.h" +#include "agg_pixfmt_rgba.h" + +namespace agg +{ + + //==========================================================one_color_function + template<class ColorT> class one_color_function + { + public: + typedef ColorT color_type; + + color_type m_color; + + one_color_function() : + m_color() + { + } + + static unsigned size() { return 1; } + + const color_type& operator [] (unsigned i) const + { + return m_color; + } + + color_type* operator [] (unsigned i) + { + return &m_color; + } + }; + + //==========================================================gradient_image + template<class ColorT> class gradient_image + { + private: + //------------ fields + typedef ColorT color_type; + typedef agg::pixfmt_rgba32 pixfmt_type; + + agg::rgba8* m_buffer; + + int m_alocdx; + int m_alocdy; + int m_width; + int m_height; + + color_type* m_color; + + one_color_function<color_type> m_color_function; + + public: + gradient_image() : + m_color_function(), + m_buffer(NULL), + m_alocdx(0), + m_alocdy(0), + m_width(0), + m_height(0) + { + m_color = m_color_function[0 ]; + } + + ~gradient_image() + { + if (m_buffer) { delete [] m_buffer; } + } + + void* image_create(int width, int height ) + { + void* result = NULL; + + if (width > m_alocdx || height > m_alocdy) + { + if (m_buffer) { delete [] m_buffer; } + + m_buffer = NULL; + m_buffer = new agg::rgba8[width * height]; + + if (m_buffer) + { + m_alocdx = width; + m_alocdy = height; + } + else + { + m_alocdx = 0; + m_alocdy = 0; + }; + }; + + if (m_buffer) + { + m_width = width; + m_height = height; + + for (int rows = 0; rows < height; rows++) + { + agg::rgba8* row = &m_buffer[rows * m_alocdx ]; + std::memset(row ,0 ,m_width * 4 ); + }; + + result = m_buffer; + }; + return result; + } + + void* image_buffer() { return m_buffer; } + int image_width() { return m_width; } + int image_height() { return m_height; } + int image_stride() { return m_alocdx * 4; } + + int calculate(int x, int y, int d) const + { + if (m_buffer) + { + int px = x >> agg::gradient_subpixel_shift; + int py = y >> agg::gradient_subpixel_shift; + + px %= m_width; + + if (px < 0) + { + px += m_width; + } + + py %= m_height; + + if (py < 0 ) + { + py += m_height; + } + + rgba8* pixel = &m_buffer[py * m_alocdx + px ]; + + m_color->r = pixel->r; + m_color->g = pixel->g; + m_color->b = pixel->b; + m_color->a = pixel->a; + + } + else + { + m_color->r = 0; + m_color->g = 0; + m_color->b = 0; + m_color->a = 0; + } + return 0; + } + + const one_color_function<color_type>& color_function() const + { + return m_color_function; + } + + }; + +} + +#endif diff --git a/include/agg_span_image_filter.h b/include/agg_span_image_filter.h new file mode 100644 index 0000000..9d0a10a --- /dev/null +++ b/include/agg_span_image_filter.h @@ -0,0 +1,247 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Image transformations with filtering. Span generator base class +// +//---------------------------------------------------------------------------- +#ifndef AGG_SPAN_IMAGE_FILTER_INCLUDED +#define AGG_SPAN_IMAGE_FILTER_INCLUDED + +#include "agg_basics.h" +#include "agg_image_filters.h" +#include "agg_span_interpolator_linear.h" + +namespace agg +{ + + //-------------------------------------------------------span_image_filter + template<class Source, class Interpolator> class span_image_filter + { + public: + typedef Source source_type; + typedef Interpolator interpolator_type; + + //-------------------------------------------------------------------- + span_image_filter() {} + span_image_filter(source_type& src, + interpolator_type& interpolator, + image_filter_lut* filter) : + m_src(&src), + m_interpolator(&interpolator), + m_filter(filter), + m_dx_dbl(0.5), + m_dy_dbl(0.5), + m_dx_int(image_subpixel_scale / 2), + m_dy_int(image_subpixel_scale / 2) + {} + void attach(source_type& v) { m_src = &v; } + + //-------------------------------------------------------------------- + source_type& source() { return *m_src; } + const source_type& source() const { return *m_src; } + const image_filter_lut& filter() const { return *m_filter; } + int filter_dx_int() const { return m_dx_int; } + int filter_dy_int() const { return m_dy_int; } + double filter_dx_dbl() const { return m_dx_dbl; } + double filter_dy_dbl() const { return m_dy_dbl; } + + //-------------------------------------------------------------------- + void interpolator(interpolator_type& v) { m_interpolator = &v; } + void filter(image_filter_lut& v) { m_filter = &v; } + void filter_offset(double dx, double dy) + { + m_dx_dbl = dx; + m_dy_dbl = dy; + m_dx_int = iround(dx * image_subpixel_scale); + m_dy_int = iround(dy * image_subpixel_scale); + } + void filter_offset(double d) { filter_offset(d, d); } + + //-------------------------------------------------------------------- + interpolator_type& interpolator() { return *m_interpolator; } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + private: + source_type* m_src; + interpolator_type* m_interpolator; + image_filter_lut* m_filter; + double m_dx_dbl; + double m_dy_dbl; + unsigned m_dx_int; + unsigned m_dy_int; + }; + + + + + //==============================================span_image_resample_affine + template<class Source> + class span_image_resample_affine : + public span_image_filter<Source, span_interpolator_linear<trans_affine> > + { + public: + typedef Source source_type; + typedef span_interpolator_linear<trans_affine> interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + + //-------------------------------------------------------------------- + span_image_resample_affine() : + m_scale_limit(200.0), + m_blur_x(1.0), + m_blur_y(1.0) + {} + + //-------------------------------------------------------------------- + span_image_resample_affine(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, &filter), + m_scale_limit(200.0), + m_blur_x(1.0), + m_blur_y(1.0) + {} + + + //-------------------------------------------------------------------- + int scale_limit() const { return uround(m_scale_limit); } + void scale_limit(int v) { m_scale_limit = v; } + + //-------------------------------------------------------------------- + double blur_x() const { return m_blur_x; } + double blur_y() const { return m_blur_y; } + void blur_x(double v) { m_blur_x = v; } + void blur_y(double v) { m_blur_y = v; } + void blur(double v) { m_blur_x = m_blur_y = v; } + + //-------------------------------------------------------------------- + void prepare() + { + double scale_x; + double scale_y; + + base_type::interpolator().transformer().scaling_abs(&scale_x, &scale_y); + + double scale_xy = scale_x * scale_y; + if (scale_xy > m_scale_limit) + { + scale_x = scale_x * m_scale_limit / scale_xy; + scale_y = scale_y * m_scale_limit / scale_xy; + } + + if(scale_x < 1) scale_x = 1; + if(scale_y < 1) scale_y = 1; + + if(scale_x > m_scale_limit) scale_x = m_scale_limit; + if(scale_y > m_scale_limit) scale_y = m_scale_limit; + + scale_x *= m_blur_x; + scale_y *= m_blur_y; + + if(scale_x < 1) scale_x = 1; + if(scale_y < 1) scale_y = 1; + + m_rx = uround( scale_x * double(image_subpixel_scale)); + m_rx_inv = uround(1.0/scale_x * double(image_subpixel_scale)); + + m_ry = uround( scale_y * double(image_subpixel_scale)); + m_ry_inv = uround(1.0/scale_y * double(image_subpixel_scale)); + } + + protected: + int m_rx; + int m_ry; + int m_rx_inv; + int m_ry_inv; + + private: + double m_scale_limit; + double m_blur_x; + double m_blur_y; + }; + + + + //=====================================================span_image_resample + template<class Source, class Interpolator> + class span_image_resample : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + + //-------------------------------------------------------------------- + span_image_resample() : + m_scale_limit(20), + m_blur_x(image_subpixel_scale), + m_blur_y(image_subpixel_scale) + {} + + //-------------------------------------------------------------------- + span_image_resample(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, &filter), + m_scale_limit(20), + m_blur_x(image_subpixel_scale), + m_blur_y(image_subpixel_scale) + {} + + //-------------------------------------------------------------------- + int scale_limit() const { return m_scale_limit; } + void scale_limit(int v) { m_scale_limit = v; } + + //-------------------------------------------------------------------- + double blur_x() const { return double(m_blur_x) / double(image_subpixel_scale); } + double blur_y() const { return double(m_blur_y) / double(image_subpixel_scale); } + void blur_x(double v) { m_blur_x = uround(v * double(image_subpixel_scale)); } + void blur_y(double v) { m_blur_y = uround(v * double(image_subpixel_scale)); } + void blur(double v) { m_blur_x = + m_blur_y = uround(v * double(image_subpixel_scale)); } + + protected: + AGG_INLINE void adjust_scale(int* rx, int* ry) + { + if(*rx < image_subpixel_scale) *rx = image_subpixel_scale; + if(*ry < image_subpixel_scale) *ry = image_subpixel_scale; + if(*rx > image_subpixel_scale * m_scale_limit) + { + *rx = image_subpixel_scale * m_scale_limit; + } + if(*ry > image_subpixel_scale * m_scale_limit) + { + *ry = image_subpixel_scale * m_scale_limit; + } + *rx = (*rx * m_blur_x) >> image_subpixel_shift; + *ry = (*ry * m_blur_y) >> image_subpixel_shift; + if(*rx < image_subpixel_scale) *rx = image_subpixel_scale; + if(*ry < image_subpixel_scale) *ry = image_subpixel_scale; + } + + int m_scale_limit; + int m_blur_x; + int m_blur_y; + }; + + + + +} + +#endif diff --git a/include/agg_span_image_filter_gray.h b/include/agg_span_image_filter_gray.h new file mode 100644 index 0000000..e2c688e --- /dev/null +++ b/include/agg_span_image_filter_gray.h @@ -0,0 +1,723 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_SPAN_IMAGE_FILTER_GRAY_INCLUDED +#define AGG_SPAN_IMAGE_FILTER_GRAY_INCLUDED + +#include "agg_basics.h" +#include "agg_color_gray.h" +#include "agg_span_image_filter.h" + + +namespace agg +{ + + //==============================================span_image_filter_gray_nn + template<class Source, class Interpolator> + class span_image_filter_gray_nn : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_gray_nn() {} + span_image_filter_gray_nn(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + do + { + base_type::interpolator().coordinates(&x, &y); + span->v = *(const value_type*) + base_type::source().span(x >> image_subpixel_shift, + y >> image_subpixel_shift, + 1); + span->a = color_type::full_value(); + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //=========================================span_image_filter_gray_bilinear + template<class Source, class Interpolator> + class span_image_filter_gray_bilinear : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_gray_bilinear() {} + span_image_filter_gray_bilinear(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg; + const value_type *fg_ptr; + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + fg = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + fg += *fg_ptr * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr); + + fg_ptr = (const value_type*)base_type::source().next_x(); + fg += *fg_ptr * x_hr * (image_subpixel_scale - y_hr); + + fg_ptr = (const value_type*)base_type::source().next_y(); + fg += *fg_ptr * (image_subpixel_scale - x_hr) * y_hr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + fg += *fg_ptr * x_hr * y_hr; + + span->v = color_type::downshift(fg, image_subpixel_shift * 2); + span->a = color_type::full_value(); + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + //====================================span_image_filter_gray_bilinear_clip + template<class Source, class Interpolator> + class span_image_filter_gray_bilinear_clip : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_gray_bilinear_clip() {} + span_image_filter_gray_bilinear_clip(source_type& src, + const color_type& back_color, + interpolator_type& inter) : + base_type(src, inter, 0), + m_back_color(back_color) + {} + const color_type& background_color() const { return m_back_color; } + void background_color(const color_type& v) { m_back_color = v; } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg; + long_type src_alpha; + value_type back_v = m_back_color.v; + value_type back_a = m_back_color.a; + + const value_type *fg_ptr; + + int maxx = base_type::source().width() - 1; + int maxy = base_type::source().height() - 1; + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + if(x_lr >= 0 && y_lr >= 0 && + x_lr < maxx && y_lr < maxy) + { + fg = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr; + + fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr); + fg += *fg_ptr++ * (image_subpixel_scale - y_hr) * x_hr; + + ++y_lr; + fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr; + + fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * y_hr; + fg += *fg_ptr++ * x_hr * y_hr; + + fg = color_type::downshift(fg, image_subpixel_shift * 2); + src_alpha = color_type::full_value(); + } + else + { + unsigned weight; + if(x_lr < -1 || y_lr < -1 || + x_lr > maxx || y_lr > maxy) + { + fg = back_v; + src_alpha = back_a; + } + else + { + fg = src_alpha = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * color_type::full_value(); + } + else + { + fg += back_v * weight; + src_alpha += back_a * weight; + } + + x_lr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * color_type::full_value(); + } + else + { + fg += back_v * weight; + src_alpha += back_a * weight; + } + + x_lr--; + y_lr++; + + weight = (image_subpixel_scale - x_hr) * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * color_type::full_value(); + } + else + { + fg += back_v * weight; + src_alpha += back_a * weight; + } + + x_lr++; + + weight = x_hr * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * color_type::full_value(); + } + else + { + fg += back_v * weight; + src_alpha += back_a * weight; + } + + fg = color_type::downshift(fg, image_subpixel_shift * 2); + src_alpha = color_type::downshift(src_alpha, image_subpixel_shift * 2); + } + } + + span->v = (value_type)fg; + span->a = (value_type)src_alpha; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + private: + color_type m_back_color; + }; + + + + //==============================================span_image_filter_gray_2x2 + template<class Source, class Interpolator> + class span_image_filter_gray_2x2 : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_gray_2x2() {} + span_image_filter_gray_2x2(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg; + + const value_type *fg_ptr; + const int16* weight_array = base_type::filter().weight_array() + + ((base_type::filter().diameter()/2 - 1) << + image_subpixel_shift); + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + fg = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg >>= image_filter_shift; + if(fg > color_type::full_value()) fg = color_type::full_value(); + + span->v = (value_type)fg; + span->a = color_type::full_value(); + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //==================================================span_image_filter_gray + template<class Source, class Interpolator> + class span_image_filter_gray : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_gray() {} + span_image_filter_gray(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg; + const value_type *fg_ptr; + + unsigned diameter = base_type::filter().diameter(); + int start = base_type::filter().start(); + const int16* weight_array = base_type::filter().weight_array(); + + int x_count; + int weight_y; + + do + { + base_type::interpolator().coordinates(&x, &y); + + x -= base_type::filter_dx_int(); + y -= base_type::filter_dy_int(); + + int x_hr = x; + int y_hr = y; + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + fg = 0; + + int x_fract = x_hr & image_subpixel_mask; + unsigned y_count = diameter; + + y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); + fg_ptr = (const value_type*)base_type::source().span(x_lr + start, + y_lr + start, + diameter); + for(;;) + { + x_count = diameter; + weight_y = weight_array[y_hr]; + x_hr = image_subpixel_mask - x_fract; + for(;;) + { + fg += *fg_ptr * + ((weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + image_filter_shift); + if(--x_count == 0) break; + x_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + + if(--y_count == 0) break; + y_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg = color_type::downshift(fg, image_filter_shift); + if(fg < 0) fg = 0; + if(fg > color_type::full_value()) fg = color_type::full_value(); + span->v = (value_type)fg; + span->a = color_type::full_value(); + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //=========================================span_image_resample_gray_affine + template<class Source> + class span_image_resample_gray_affine : + public span_image_resample_affine<Source> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef span_image_resample_affine<source_type> base_type; + typedef typename base_type::interpolator_type interpolator_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_gray_affine() {} + span_image_resample_gray_affine(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + int radius_x = (diameter * base_type::m_rx) >> 1; + int radius_y = (diameter * base_type::m_ry) >> 1; + int len_x_lr = + (diameter * base_type::m_rx + image_subpixel_mask) >> + image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + + do + { + base_type::interpolator().coordinates(&x, &y); + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg = 0; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + base_type::m_ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + base_type::m_rx_inv) >> + image_subpixel_shift; + + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + + fg += *fg_ptr * weight; + total_weight += weight; + x_hr += base_type::m_rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += base_type::m_ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg /= total_weight; + if(fg < 0) fg = 0; + if(fg > color_type::full_value()) fg = color_type::full_value(); + + span->v = (value_type)fg; + span->a = color_type::full_value(); + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //================================================span_image_resample_gray + template<class Source, class Interpolator> + class span_image_resample_gray : + public span_image_resample<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_resample<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_gray() {} + span_image_resample_gray(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + do + { + int rx; + int ry; + int rx_inv = image_subpixel_scale; + int ry_inv = image_subpixel_scale; + base_type::interpolator().coordinates(&x, &y); + base_type::interpolator().local_scale(&rx, &ry); + base_type::adjust_scale(&rx, &ry); + + rx_inv = image_subpixel_scale * image_subpixel_scale / rx; + ry_inv = image_subpixel_scale * image_subpixel_scale / ry; + + int radius_x = (diameter * rx) >> 1; + int radius_y = (diameter * ry) >> 1; + int len_x_lr = + (diameter * rx + image_subpixel_mask) >> + image_subpixel_shift; + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg = 0; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + rx_inv) >> + image_subpixel_shift; + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + fg += *fg_ptr * weight; + total_weight += weight; + x_hr += rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg /= total_weight; + if(fg < 0) fg = 0; + if(fg > color_type::full_value()) fg = color_type::full_value(); + + span->v = (value_type)fg; + span->a = color_type::full_value(); + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + +} + + +#endif + + + diff --git a/include/agg_span_image_filter_rgb.h b/include/agg_span_image_filter_rgb.h new file mode 100644 index 0000000..f78ae19 --- /dev/null +++ b/include/agg_span_image_filter_rgb.h @@ -0,0 +1,861 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED +#define AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED + +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_span_image_filter.h" + + +namespace agg +{ + + //===============================================span_image_filter_rgb_nn + template<class Source, class Interpolator> + class span_image_filter_rgb_nn : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgb_nn() {} + span_image_filter_rgb_nn(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + do + { + base_type::interpolator().coordinates(&x, &y); + const value_type* fg_ptr = (const value_type*) + base_type::source().span(x >> image_subpixel_shift, + y >> image_subpixel_shift, + 1); + span->r = fg_ptr[order_type::R]; + span->g = fg_ptr[order_type::G]; + span->b = fg_ptr[order_type::B]; + span->a = color_type::full_value(); + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //==========================================span_image_filter_rgb_bilinear + template<class Source, class Interpolator> + class span_image_filter_rgb_bilinear : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgb_bilinear() {} + span_image_filter_rgb_bilinear(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg[3]; + const value_type *fg_ptr; + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + + fg[0] = fg[1] = fg[2] = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = x_hr * (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (image_subpixel_scale - x_hr) * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = x_hr * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + span->r = color_type::downshift(fg[order_type::R], image_subpixel_shift * 2); + span->g = color_type::downshift(fg[order_type::G], image_subpixel_shift * 2); + span->b = color_type::downshift(fg[order_type::B], image_subpixel_shift * 2); + span->a = color_type::full_value(); + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //=====================================span_image_filter_rgb_bilinear_clip + template<class Source, class Interpolator> + class span_image_filter_rgb_bilinear_clip : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgb_bilinear_clip() {} + span_image_filter_rgb_bilinear_clip(source_type& src, + const color_type& back_color, + interpolator_type& inter) : + base_type(src, inter, 0), + m_back_color(back_color) + {} + const color_type& background_color() const { return m_back_color; } + void background_color(const color_type& v) { m_back_color = v; } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg[3]; + long_type src_alpha; + value_type back_r = m_back_color.r; + value_type back_g = m_back_color.g; + value_type back_b = m_back_color.b; + value_type back_a = m_back_color.a; + + const value_type *fg_ptr; + + int maxx = base_type::source().width() - 1; + int maxy = base_type::source().height() - 1; + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + unsigned weight; + + if(x_lr >= 0 && y_lr >= 0 && + x_lr < maxx && y_lr < maxy) + { + fg[0] = fg[1] = fg[2] = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + + ++y_lr; + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + weight = (image_subpixel_scale - x_hr) * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + + weight = x_hr * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + + fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2); + fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2); + fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2); + src_alpha = color_type::full_value(); + } + else + { + if(x_lr < -1 || y_lr < -1 || + x_lr > maxx || y_lr > maxy) + { + fg[order_type::R] = back_r; + fg[order_type::G] = back_g; + fg[order_type::B] = back_b; + src_alpha = back_a; + } + else + { + fg[0] = fg[1] = fg[2] = src_alpha = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + src_alpha += weight * color_type::full_value(); + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + src_alpha += back_a * weight; + } + + x_lr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + src_alpha += weight * color_type::full_value(); + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + src_alpha += back_a * weight; + } + + x_lr--; + y_lr++; + + weight = (image_subpixel_scale - x_hr) * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + src_alpha += weight * color_type::full_value(); + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + src_alpha += back_a * weight; + } + + x_lr++; + + weight = x_hr * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + src_alpha += weight * color_type::full_value(); + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + src_alpha += back_a * weight; + } + + fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2); + fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2); + fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2); + src_alpha = color_type::downshift(src_alpha, image_subpixel_shift * 2); + } + } + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)src_alpha; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + private: + color_type m_back_color; + }; + + + + //===============================================span_image_filter_rgb_2x2 + template<class Source, class Interpolator> + class span_image_filter_rgb_2x2 : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgb_2x2() {} + span_image_filter_rgb_2x2(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[3]; + + const value_type *fg_ptr; + const int16* weight_array = base_type::filter().weight_array() + + ((base_type::filter().diameter()/2 - 1) << + image_subpixel_shift); + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + fg[0] = fg[1] = fg[2] = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + fg[0] = color_type::downshift(fg[0], image_filter_shift); + fg[1] = color_type::downshift(fg[1], image_filter_shift); + fg[2] = color_type::downshift(fg[2], image_filter_shift); + + if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value(); + if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value(); + if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value(); + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = color_type::full_value(); + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //===================================================span_image_filter_rgb + template<class Source, class Interpolator> + class span_image_filter_rgb : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgb() {} + span_image_filter_rgb(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[3]; + const value_type *fg_ptr; + + unsigned diameter = base_type::filter().diameter(); + int start = base_type::filter().start(); + const int16* weight_array = base_type::filter().weight_array(); + + int x_count; + int weight_y; + + do + { + base_type::interpolator().coordinates(&x, &y); + + x -= base_type::filter_dx_int(); + y -= base_type::filter_dy_int(); + + int x_hr = x; + int y_hr = y; + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + fg[0] = fg[1] = fg[2] = 0; + + int x_fract = x_hr & image_subpixel_mask; + unsigned y_count = diameter; + + y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); + fg_ptr = (const value_type*)base_type::source().span(x_lr + start, + y_lr + start, + diameter); + for(;;) + { + x_count = diameter; + weight_y = weight_array[y_hr]; + x_hr = image_subpixel_mask - x_fract; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + image_filter_shift; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr; + + if(--x_count == 0) break; + x_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + + if(--y_count == 0) break; + y_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] = color_type::downshift(fg[0], image_filter_shift); + fg[1] = color_type::downshift(fg[1], image_filter_shift); + fg[2] = color_type::downshift(fg[2], image_filter_shift); + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + + if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value(); + if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value(); + if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value(); + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = color_type::full_value(); + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //==========================================span_image_resample_rgb_affine + template<class Source> + class span_image_resample_rgb_affine : + public span_image_resample_affine<Source> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef span_image_resample_affine<source_type> base_type; + typedef typename base_type::interpolator_type interpolator_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_rgb_affine() {} + span_image_resample_rgb_affine(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[3]; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + int radius_x = (diameter * base_type::m_rx) >> 1; + int radius_y = (diameter * base_type::m_ry) >> 1; + int len_x_lr = + (diameter * base_type::m_rx + image_subpixel_mask) >> + image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + + do + { + base_type::interpolator().coordinates(&x, &y); + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg[0] = fg[1] = fg[2] = 0; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + base_type::m_ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + base_type::m_rx_inv) >> + image_subpixel_shift; + + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + + fg[0] += *fg_ptr++ * weight; + fg[1] += *fg_ptr++ * weight; + fg[2] += *fg_ptr * weight; + total_weight += weight; + x_hr += base_type::m_rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += base_type::m_ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] /= total_weight; + fg[1] /= total_weight; + fg[2] /= total_weight; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + + if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value(); + if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value(); + if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value(); + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = color_type::full_value(); + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //=================================================span_image_resample_rgb + template<class Source, class Interpolator> + class span_image_resample_rgb : + public span_image_resample<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_resample<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_rgb() {} + span_image_resample_rgb(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg[3]; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + do + { + int rx; + int ry; + int rx_inv = image_subpixel_scale; + int ry_inv = image_subpixel_scale; + base_type::interpolator().coordinates(&x, &y); + base_type::interpolator().local_scale(&rx, &ry); + base_type::adjust_scale(&rx, &ry); + + rx_inv = image_subpixel_scale * image_subpixel_scale / rx; + ry_inv = image_subpixel_scale * image_subpixel_scale / ry; + + int radius_x = (diameter * rx) >> 1; + int radius_y = (diameter * ry) >> 1; + int len_x_lr = + (diameter * rx + image_subpixel_mask) >> + image_subpixel_shift; + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg[0] = fg[1] = fg[2] = 0; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + rx_inv) >> + image_subpixel_shift; + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + fg[0] += *fg_ptr++ * weight; + fg[1] += *fg_ptr++ * weight; + fg[2] += *fg_ptr * weight; + total_weight += weight; + x_hr += rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] /= total_weight; + fg[1] /= total_weight; + fg[2] /= total_weight; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + + if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value(); + if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value(); + if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value(); + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = color_type::full_value(); + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + +} + + +#endif + + + diff --git a/include/agg_span_image_filter_rgba.h b/include/agg_span_image_filter_rgba.h new file mode 100644 index 0000000..af7a1a2 --- /dev/null +++ b/include/agg_span_image_filter_rgba.h @@ -0,0 +1,890 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_SPAN_IMAGE_FILTER_RGBA_INCLUDED +#define AGG_SPAN_IMAGE_FILTER_RGBA_INCLUDED + +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_span_image_filter.h" + + +namespace agg +{ + + //==============================================span_image_filter_rgba_nn + template<class Source, class Interpolator> + class span_image_filter_rgba_nn : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgba_nn() {} + span_image_filter_rgba_nn(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + do + { + base_type::interpolator().coordinates(&x, &y); + const value_type* fg_ptr = (const value_type*) + base_type::source().span(x >> image_subpixel_shift, + y >> image_subpixel_shift, + 1); + span->r = fg_ptr[order_type::R]; + span->g = fg_ptr[order_type::G]; + span->b = fg_ptr[order_type::B]; + span->a = fg_ptr[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //=========================================span_image_filter_rgba_bilinear + template<class Source, class Interpolator> + class span_image_filter_rgba_bilinear : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgba_bilinear() {} + span_image_filter_rgba_bilinear(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[4]; + const value_type *fg_ptr; + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + + fg[0] = + fg[1] = + fg[2] = + fg[3] = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = x_hr * (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (image_subpixel_scale - x_hr) * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = x_hr * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + span->r = value_type(color_type::downshift(fg[order_type::R], image_subpixel_shift * 2)); + span->g = value_type(color_type::downshift(fg[order_type::G], image_subpixel_shift * 2)); + span->b = value_type(color_type::downshift(fg[order_type::B], image_subpixel_shift * 2)); + span->a = value_type(color_type::downshift(fg[order_type::A], image_subpixel_shift * 2)); + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + //====================================span_image_filter_rgba_bilinear_clip + template<class Source, class Interpolator> + class span_image_filter_rgba_bilinear_clip : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgba_bilinear_clip() {} + span_image_filter_rgba_bilinear_clip(source_type& src, + const color_type& back_color, + interpolator_type& inter) : + base_type(src, inter, 0), + m_back_color(back_color) + {} + const color_type& background_color() const { return m_back_color; } + void background_color(const color_type& v) { m_back_color = v; } + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[4]; + value_type back_r = m_back_color.r; + value_type back_g = m_back_color.g; + value_type back_b = m_back_color.b; + value_type back_a = m_back_color.a; + + const value_type *fg_ptr; + int maxx = base_type::source().width() - 1; + int maxy = base_type::source().height() - 1; + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + + if(x_lr >= 0 && y_lr >= 0 && + x_lr < maxx && y_lr < maxy) + { + fg[0] = fg[1] = fg[2] = fg[3] = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + ++y_lr; + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + weight = (image_subpixel_scale - x_hr) * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + weight = x_hr * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2); + fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2); + fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2); + fg[3] = color_type::downshift(fg[3], image_subpixel_shift * 2); + } + else + { + if(x_lr < -1 || y_lr < -1 || + x_lr > maxx || y_lr > maxy) + { + fg[order_type::R] = back_r; + fg[order_type::G] = back_g; + fg[order_type::B] = back_b; + fg[order_type::A] = back_a; + } + else + { + fg[0] = fg[1] = fg[2] = fg[3] = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + x_lr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + x_lr--; + y_lr++; + + weight = (image_subpixel_scale - x_hr) * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + x_lr++; + + weight = x_hr * y_hr; + if(x_lr >= 0 && y_lr >= 0 && + x_lr <= maxx && y_lr <= maxy) + { + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2); + fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2); + fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2); + fg[3] = color_type::downshift(fg[3], image_subpixel_shift * 2); + } + } + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + private: + color_type m_back_color; + }; + + + //==============================================span_image_filter_rgba_2x2 + template<class Source, class Interpolator> + class span_image_filter_rgba_2x2 : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgba_2x2() {} + span_image_filter_rgba_2x2(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[4]; + + const value_type *fg_ptr; + const int16* weight_array = base_type::filter().weight_array() + + ((base_type::filter().diameter()/2 - 1) << + image_subpixel_shift); + + do + { + int x_hr; + int y_hr; + + base_type::interpolator().coordinates(&x_hr, &y_hr); + + x_hr -= base_type::filter_dx_int(); + y_hr -= base_type::filter_dy_int(); + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + unsigned weight; + fg[0] = fg[1] = fg[2] = fg[3] = 0; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg[0] = color_type::downshift(fg[0], image_filter_shift); + fg[1] = color_type::downshift(fg[1], image_filter_shift); + fg[2] = color_type::downshift(fg[2], image_filter_shift); + fg[3] = color_type::downshift(fg[3], image_filter_shift); + + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); + if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; + if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; + if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //==================================================span_image_filter_rgba + template<class Source, class Interpolator> + class span_image_filter_rgba : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgba() {} + span_image_filter_rgba(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, &filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[4]; + const value_type *fg_ptr; + + unsigned diameter = base_type::filter().diameter(); + int start = base_type::filter().start(); + const int16* weight_array = base_type::filter().weight_array(); + + int x_count; + int weight_y; + + do + { + base_type::interpolator().coordinates(&x, &y); + + x -= base_type::filter_dx_int(); + y -= base_type::filter_dy_int(); + + int x_hr = x; + int y_hr = y; + + int x_lr = x_hr >> image_subpixel_shift; + int y_lr = y_hr >> image_subpixel_shift; + + fg[0] = fg[1] = fg[2] = fg[3] = 0; + + int x_fract = x_hr & image_subpixel_mask; + unsigned y_count = diameter; + + y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask); + fg_ptr = (const value_type*)base_type::source().span(x_lr + start, + y_lr + start, + diameter); + for(;;) + { + x_count = diameter; + weight_y = weight_array[y_hr]; + x_hr = image_subpixel_mask - x_fract; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + image_filter_shift; + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + if(--x_count == 0) break; + x_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + + if(--y_count == 0) break; + y_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] = color_type::downshift(fg[0], image_filter_shift); + fg[1] = color_type::downshift(fg[1], image_filter_shift); + fg[2] = color_type::downshift(fg[2], image_filter_shift); + fg[3] = color_type::downshift(fg[3], image_filter_shift); + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + if(fg[3] < 0) fg[3] = 0; + + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); + if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; + if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; + if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //========================================span_image_resample_rgba_affine + template<class Source> + class span_image_resample_rgba_affine : + public span_image_resample_affine<Source> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef span_image_resample_affine<source_type> base_type; + typedef typename base_type::interpolator_type interpolator_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_rgba_affine() {} + span_image_resample_rgba_affine(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[4]; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + int radius_x = (diameter * base_type::m_rx) >> 1; + int radius_y = (diameter * base_type::m_ry) >> 1; + int len_x_lr = + (diameter * base_type::m_rx + image_subpixel_mask) >> + image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + + do + { + base_type::interpolator().coordinates(&x, &y); + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg[0] = fg[1] = fg[2] = fg[3] = 0; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + base_type::m_ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + base_type::m_rx_inv) >> + image_subpixel_shift; + + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + + fg[0] += *fg_ptr++ * weight; + fg[1] += *fg_ptr++ * weight; + fg[2] += *fg_ptr++ * weight; + fg[3] += *fg_ptr++ * weight; + total_weight += weight; + x_hr += base_type::m_rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += base_type::m_ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] /= total_weight; + fg[1] /= total_weight; + fg[2] /= total_weight; + fg[3] /= total_weight; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + if(fg[3] < 0) fg[3] = 0; + + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); + if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; + if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; + if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //==============================================span_image_resample_rgba + template<class Source, class Interpolator> + class span_image_resample_rgba : + public span_image_resample<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_resample<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_rgba() {} + span_image_resample_rgba(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, filter) + {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg[4]; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + do + { + int rx; + int ry; + int rx_inv = image_subpixel_scale; + int ry_inv = image_subpixel_scale; + base_type::interpolator().coordinates(&x, &y); + base_type::interpolator().local_scale(&rx, &ry); + base_type::adjust_scale(&rx, &ry); + + rx_inv = image_subpixel_scale * image_subpixel_scale / rx; + ry_inv = image_subpixel_scale * image_subpixel_scale / ry; + + int radius_x = (diameter * rx) >> 1; + int radius_y = (diameter * ry) >> 1; + int len_x_lr = + (diameter * rx + image_subpixel_mask) >> + image_subpixel_shift; + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg[0] = fg[1] = fg[2] = fg[3] = 0; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + rx_inv) >> + image_subpixel_shift; + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + fg[0] += *fg_ptr++ * weight; + fg[1] += *fg_ptr++ * weight; + fg[2] += *fg_ptr++ * weight; + fg[3] += *fg_ptr++ * weight; + total_weight += weight; + x_hr += rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] /= total_weight; + fg[1] /= total_weight; + fg[2] /= total_weight; + fg[3] /= total_weight; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + if(fg[3] < 0) fg[3] = 0; + + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); + if(fg[order_type::R] > fg[order_type::R]) fg[order_type::R] = fg[order_type::R]; + if(fg[order_type::G] > fg[order_type::G]) fg[order_type::G] = fg[order_type::G]; + if(fg[order_type::B] > fg[order_type::B]) fg[order_type::B] = fg[order_type::B]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + +} + + +#endif + + + diff --git a/include/agg_span_interpolator_adaptor.h b/include/agg_span_interpolator_adaptor.h new file mode 100644 index 0000000..0fdfa77 --- /dev/null +++ b/include/agg_span_interpolator_adaptor.h @@ -0,0 +1,77 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_INTERPOLATOR_ADAPTOR_INCLUDED +#define AGG_SPAN_INTERPOLATOR_ADAPTOR_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //===============================================span_interpolator_adaptor + template<class Interpolator, class Distortion> + class span_interpolator_adaptor : public Interpolator + { + public: + typedef Interpolator base_type; + typedef typename base_type::trans_type trans_type; + typedef Distortion distortion_type; + + //-------------------------------------------------------------------- + span_interpolator_adaptor() {} + span_interpolator_adaptor(trans_type& trans, + distortion_type& dist) : + base_type(trans), + m_distortion(&dist) + { + } + + //-------------------------------------------------------------------- + span_interpolator_adaptor(trans_type& trans, + distortion_type& dist, + double x, double y, unsigned len) : + base_type(trans, x, y, len), + m_distortion(&dist) + { + } + + //-------------------------------------------------------------------- + distortion_type& distortion() const + { + return *m_distortion; + } + + //-------------------------------------------------------------------- + void distortion(distortion_type& dist) + { + m_distortion = dist; + } + + //-------------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + base_type::coordinates(x, y); + m_distortion->calculate(x, y); + } + + private: + //-------------------------------------------------------------------- + distortion_type* m_distortion; + }; +} + + +#endif diff --git a/include/agg_span_interpolator_linear.h b/include/agg_span_interpolator_linear.h new file mode 100644 index 0000000..ef10505 --- /dev/null +++ b/include/agg_span_interpolator_linear.h @@ -0,0 +1,232 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED +#define AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED + +#include "agg_basics.h" +#include "agg_dda_line.h" +#include "agg_trans_affine.h" + +namespace agg +{ + + //================================================span_interpolator_linear + template<class Transformer = trans_affine, unsigned SubpixelShift = 8> + class span_interpolator_linear + { + public: + typedef Transformer trans_type; + + enum subpixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + //-------------------------------------------------------------------- + span_interpolator_linear() {} + span_interpolator_linear(trans_type& trans) : m_trans(&trans) {} + span_interpolator_linear(trans_type& trans, + double x, double y, unsigned len) : + m_trans(&trans) + { + begin(x, y, len); + } + + //---------------------------------------------------------------- + const trans_type& transformer() const { return *m_trans; } + void transformer(trans_type& trans) { m_trans = &trans; } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned len) + { + double tx; + double ty; + + tx = x; + ty = y; + m_trans->transform(&tx, &ty); + int x1 = iround(tx * subpixel_scale); + int y1 = iround(ty * subpixel_scale); + + tx = x + len; + ty = y; + m_trans->transform(&tx, &ty); + int x2 = iround(tx * subpixel_scale); + int y2 = iround(ty * subpixel_scale); + + m_li_x = dda2_line_interpolator(x1, x2, len); + m_li_y = dda2_line_interpolator(y1, y2, len); + } + + //---------------------------------------------------------------- + void resynchronize(double xe, double ye, unsigned len) + { + m_trans->transform(&xe, &ye); + m_li_x = dda2_line_interpolator(m_li_x.y(), iround(xe * subpixel_scale), len); + m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ye * subpixel_scale), len); + } + + //---------------------------------------------------------------- + void operator++() + { + ++m_li_x; + ++m_li_y; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + *x = m_li_x.y(); + *y = m_li_y.y(); + } + + private: + trans_type* m_trans; + dda2_line_interpolator m_li_x; + dda2_line_interpolator m_li_y; + }; + + + + + + + //=====================================span_interpolator_linear_subdiv + template<class Transformer = trans_affine, unsigned SubpixelShift = 8> + class span_interpolator_linear_subdiv + { + public: + typedef Transformer trans_type; + + enum subpixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + + //---------------------------------------------------------------- + span_interpolator_linear_subdiv() : + m_subdiv_shift(4), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1) {} + + span_interpolator_linear_subdiv(trans_type& trans, + unsigned subdiv_shift = 4) : + m_subdiv_shift(subdiv_shift), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1), + m_trans(&trans) {} + + span_interpolator_linear_subdiv(trans_type& trans, + double x, double y, unsigned len, + unsigned subdiv_shift = 4) : + m_subdiv_shift(subdiv_shift), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1), + m_trans(&trans) + { + begin(x, y, len); + } + + //---------------------------------------------------------------- + const trans_type& transformer() const { return *m_trans; } + void transformer(const trans_type& trans) { m_trans = &trans; } + + //---------------------------------------------------------------- + unsigned subdiv_shift() const { return m_subdiv_shift; } + void subdiv_shift(unsigned shift) + { + m_subdiv_shift = shift; + m_subdiv_size = 1 << m_subdiv_shift; + m_subdiv_mask = m_subdiv_size - 1; + } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned len) + { + double tx; + double ty; + m_pos = 1; + m_src_x = iround(x * subpixel_scale) + subpixel_scale; + m_src_y = y; + m_len = len; + + if(len > m_subdiv_size) len = m_subdiv_size; + tx = x; + ty = y; + m_trans->transform(&tx, &ty); + int x1 = iround(tx * subpixel_scale); + int y1 = iround(ty * subpixel_scale); + + tx = x + len; + ty = y; + m_trans->transform(&tx, &ty); + + m_li_x = dda2_line_interpolator(x1, iround(tx * subpixel_scale), len); + m_li_y = dda2_line_interpolator(y1, iround(ty * subpixel_scale), len); + } + + //---------------------------------------------------------------- + void operator++() + { + ++m_li_x; + ++m_li_y; + if(m_pos >= m_subdiv_size) + { + unsigned len = m_len; + if(len > m_subdiv_size) len = m_subdiv_size; + double tx = double(m_src_x) / double(subpixel_scale) + len; + double ty = m_src_y; + m_trans->transform(&tx, &ty); + m_li_x = dda2_line_interpolator(m_li_x.y(), iround(tx * subpixel_scale), len); + m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ty * subpixel_scale), len); + m_pos = 0; + } + m_src_x += subpixel_scale; + ++m_pos; + --m_len; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + *x = m_li_x.y(); + *y = m_li_y.y(); + } + + private: + unsigned m_subdiv_shift; + unsigned m_subdiv_size; + unsigned m_subdiv_mask; + trans_type* m_trans; + dda2_line_interpolator m_li_x; + dda2_line_interpolator m_li_y; + int m_src_x; + double m_src_y; + unsigned m_pos; + unsigned m_len; + }; + + +} + + + +#endif + + diff --git a/include/agg_span_interpolator_persp.h b/include/agg_span_interpolator_persp.h new file mode 100644 index 0000000..15d33ba --- /dev/null +++ b/include/agg_span_interpolator_persp.h @@ -0,0 +1,463 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED +#define AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED + +#include <cmath> +#include "agg_trans_perspective.h" +#include "agg_dda_line.h" + +namespace agg +{ + + + + //===========================================span_interpolator_persp_exact + template<unsigned SubpixelShift = 8> + class span_interpolator_persp_exact + { + public: + typedef trans_perspective trans_type; + typedef trans_perspective::iterator_x iterator_type; + enum subpixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + //-------------------------------------------------------------------- + span_interpolator_persp_exact() {} + + //-------------------------------------------------------------------- + // Arbitrary quadrangle transformations + span_interpolator_persp_exact(const double* src, const double* dst) + { + quad_to_quad(src, dst); + } + + //-------------------------------------------------------------------- + // Direct transformations + span_interpolator_persp_exact(double x1, double y1, + double x2, double y2, + const double* quad) + { + rect_to_quad(x1, y1, x2, y2, quad); + } + + //-------------------------------------------------------------------- + // Reverse transformations + span_interpolator_persp_exact(const double* quad, + double x1, double y1, + double x2, double y2) + { + quad_to_rect(quad, x1, y1, x2, y2); + } + + //-------------------------------------------------------------------- + // Set the transformations using two arbitrary quadrangles. + void quad_to_quad(const double* src, const double* dst) + { + m_trans_dir.quad_to_quad(src, dst); + m_trans_inv.quad_to_quad(dst, src); + } + + //-------------------------------------------------------------------- + // Set the direct transformations, i.e., rectangle -> quadrangle + void rect_to_quad(double x1, double y1, double x2, double y2, + const double* quad) + { + double src[8]; + src[0] = src[6] = x1; + src[2] = src[4] = x2; + src[1] = src[3] = y1; + src[5] = src[7] = y2; + quad_to_quad(src, quad); + } + + + //-------------------------------------------------------------------- + // Set the reverse transformations, i.e., quadrangle -> rectangle + void quad_to_rect(const double* quad, + double x1, double y1, double x2, double y2) + { + double dst[8]; + dst[0] = dst[6] = x1; + dst[2] = dst[4] = x2; + dst[1] = dst[3] = y1; + dst[5] = dst[7] = y2; + quad_to_quad(quad, dst); + } + + //-------------------------------------------------------------------- + // Check if the equations were solved successfully + bool is_valid() const { return m_trans_dir.is_valid(); } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned len) + { + m_iterator = m_trans_dir.begin(x, y, 1.0); + double xt = m_iterator.x; + double yt = m_iterator.y; + + double dx; + double dy; + const double delta = 1/double(subpixel_scale); + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sx1 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sy1 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + x += len; + xt = x; + yt = y; + m_trans_dir.transform(&xt, &yt); + + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sx2 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sy2 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + m_scale_x = dda2_line_interpolator(sx1, sx2, len); + m_scale_y = dda2_line_interpolator(sy1, sy2, len); + } + + + //---------------------------------------------------------------- + void resynchronize(double xe, double ye, unsigned len) + { + // Assume x1,y1 are equal to the ones at the previous end point + int sx1 = m_scale_x.y(); + int sy1 = m_scale_y.y(); + + // Calculate transformed coordinates at x2,y2 + double xt = xe; + double yt = ye; + m_trans_dir.transform(&xt, &yt); + + const double delta = 1/double(subpixel_scale); + double dx; + double dy; + + // Calculate scale by X at x2,y2 + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= xe; + dy -= ye; + int sx2 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Calculate scale by Y at x2,y2 + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= xe; + dy -= ye; + int sy2 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Initialize the interpolators + m_scale_x = dda2_line_interpolator(sx1, sx2, len); + m_scale_y = dda2_line_interpolator(sy1, sy2, len); + } + + + + //---------------------------------------------------------------- + void operator++() + { + ++m_iterator; + ++m_scale_x; + ++m_scale_y; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + *x = iround(m_iterator.x * subpixel_scale); + *y = iround(m_iterator.y * subpixel_scale); + } + + //---------------------------------------------------------------- + void local_scale(int* x, int* y) + { + *x = m_scale_x.y(); + *y = m_scale_y.y(); + } + + //---------------------------------------------------------------- + void transform(double* x, double* y) const + { + m_trans_dir.transform(x, y); + } + + private: + trans_type m_trans_dir; + trans_type m_trans_inv; + iterator_type m_iterator; + dda2_line_interpolator m_scale_x; + dda2_line_interpolator m_scale_y; + }; + + + + + + + + + + + + //============================================span_interpolator_persp_lerp + template<unsigned SubpixelShift = 8> + class span_interpolator_persp_lerp + { + public: + typedef trans_perspective trans_type; + enum subpixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + //-------------------------------------------------------------------- + span_interpolator_persp_lerp() {} + + //-------------------------------------------------------------------- + // Arbitrary quadrangle transformations + span_interpolator_persp_lerp(const double* src, const double* dst) + { + quad_to_quad(src, dst); + } + + //-------------------------------------------------------------------- + // Direct transformations + span_interpolator_persp_lerp(double x1, double y1, + double x2, double y2, + const double* quad) + { + rect_to_quad(x1, y1, x2, y2, quad); + } + + //-------------------------------------------------------------------- + // Reverse transformations + span_interpolator_persp_lerp(const double* quad, + double x1, double y1, + double x2, double y2) + { + quad_to_rect(quad, x1, y1, x2, y2); + } + + //-------------------------------------------------------------------- + // Set the transformations using two arbitrary quadrangles. + void quad_to_quad(const double* src, const double* dst) + { + m_trans_dir.quad_to_quad(src, dst); + m_trans_inv.quad_to_quad(dst, src); + } + + //-------------------------------------------------------------------- + // Set the direct transformations, i.e., rectangle -> quadrangle + void rect_to_quad(double x1, double y1, double x2, double y2, + const double* quad) + { + double src[8]; + src[0] = src[6] = x1; + src[2] = src[4] = x2; + src[1] = src[3] = y1; + src[5] = src[7] = y2; + quad_to_quad(src, quad); + } + + + //-------------------------------------------------------------------- + // Set the reverse transformations, i.e., quadrangle -> rectangle + void quad_to_rect(const double* quad, + double x1, double y1, double x2, double y2) + { + double dst[8]; + dst[0] = dst[6] = x1; + dst[2] = dst[4] = x2; + dst[1] = dst[3] = y1; + dst[5] = dst[7] = y2; + quad_to_quad(quad, dst); + } + + //-------------------------------------------------------------------- + // Check if the equations were solved successfully + bool is_valid() const { return m_trans_dir.is_valid(); } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned len) + { + // Calculate transformed coordinates at x1,y1 + double xt = x; + double yt = y; + m_trans_dir.transform(&xt, &yt); + int x1 = iround(xt * subpixel_scale); + int y1 = iround(yt * subpixel_scale); + + double dx; + double dy; + const double delta = 1/double(subpixel_scale); + + // Calculate scale by X at x1,y1 + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sx1 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Calculate scale by Y at x1,y1 + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sy1 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Calculate transformed coordinates at x2,y2 + x += len; + xt = x; + yt = y; + m_trans_dir.transform(&xt, &yt); + int x2 = iround(xt * subpixel_scale); + int y2 = iround(yt * subpixel_scale); + + // Calculate scale by X at x2,y2 + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sx2 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Calculate scale by Y at x2,y2 + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= x; + dy -= y; + int sy2 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Initialize the interpolators + m_coord_x = dda2_line_interpolator(x1, x2, len); + m_coord_y = dda2_line_interpolator(y1, y2, len); + m_scale_x = dda2_line_interpolator(sx1, sx2, len); + m_scale_y = dda2_line_interpolator(sy1, sy2, len); + } + + + //---------------------------------------------------------------- + void resynchronize(double xe, double ye, unsigned len) + { + // Assume x1,y1 are equal to the ones at the previous end point + int x1 = m_coord_x.y(); + int y1 = m_coord_y.y(); + int sx1 = m_scale_x.y(); + int sy1 = m_scale_y.y(); + + // Calculate transformed coordinates at x2,y2 + double xt = xe; + double yt = ye; + m_trans_dir.transform(&xt, &yt); + int x2 = iround(xt * subpixel_scale); + int y2 = iround(yt * subpixel_scale); + + const double delta = 1/double(subpixel_scale); + double dx; + double dy; + + // Calculate scale by X at x2,y2 + dx = xt + delta; + dy = yt; + m_trans_inv.transform(&dx, &dy); + dx -= xe; + dy -= ye; + int sx2 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Calculate scale by Y at x2,y2 + dx = xt; + dy = yt + delta; + m_trans_inv.transform(&dx, &dy); + dx -= xe; + dy -= ye; + int sy2 = uround(subpixel_scale/std::sqrt(dx*dx + dy*dy)) >> subpixel_shift; + + // Initialize the interpolators + m_coord_x = dda2_line_interpolator(x1, x2, len); + m_coord_y = dda2_line_interpolator(y1, y2, len); + m_scale_x = dda2_line_interpolator(sx1, sx2, len); + m_scale_y = dda2_line_interpolator(sy1, sy2, len); + } + + + //---------------------------------------------------------------- + void operator++() + { + ++m_coord_x; + ++m_coord_y; + ++m_scale_x; + ++m_scale_y; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + *x = m_coord_x.y(); + *y = m_coord_y.y(); + } + + //---------------------------------------------------------------- + void local_scale(int* x, int* y) + { + *x = m_scale_x.y(); + *y = m_scale_y.y(); + } + + //---------------------------------------------------------------- + void transform(double* x, double* y) const + { + m_trans_dir.transform(x, y); + } + + private: + trans_type m_trans_dir; + trans_type m_trans_inv; + dda2_line_interpolator m_coord_x; + dda2_line_interpolator m_coord_y; + dda2_line_interpolator m_scale_x; + dda2_line_interpolator m_scale_y; + }; + +} + +#endif diff --git a/include/agg_span_interpolator_trans.h b/include/agg_span_interpolator_trans.h new file mode 100644 index 0000000..32bc678 --- /dev/null +++ b/include/agg_span_interpolator_trans.h @@ -0,0 +1,92 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Horizontal span interpolator for use with an arbitrary transformer +// The efficiency highly depends on the operations done in the transformer +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_INTERPOLATOR_TRANS_INCLUDED +#define AGG_SPAN_INTERPOLATOR_TRANS_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //=================================================span_interpolator_trans + template<class Transformer, unsigned SubpixelShift = 8> + class span_interpolator_trans + { + public: + typedef Transformer trans_type; + enum subpixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + //-------------------------------------------------------------------- + span_interpolator_trans() {} + span_interpolator_trans(trans_type& trans) : m_trans(&trans) {} + span_interpolator_trans(trans_type& trans, + double x, double y, unsigned) : + m_trans(&trans) + { + begin(x, y, 0); + } + + //---------------------------------------------------------------- + const trans_type& transformer() const { return *m_trans; } + void transformer(const trans_type& trans) { m_trans = &trans; } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned) + { + m_x = x; + m_y = y; + m_trans->transform(&x, &y); + m_ix = iround(x * subpixel_scale); + m_iy = iround(y * subpixel_scale); + } + + //---------------------------------------------------------------- + void operator++() + { + m_x += 1.0; + double x = m_x; + double y = m_y; + m_trans->transform(&x, &y); + m_ix = iround(x * subpixel_scale); + m_iy = iround(y * subpixel_scale); + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + *x = m_ix; + *y = m_iy; + } + + private: + trans_type* m_trans; + double m_x; + double m_y; + int m_ix; + int m_iy; + }; + +} + +#endif diff --git a/include/agg_span_pattern_gray.h b/include/agg_span_pattern_gray.h new file mode 100644 index 0000000..ae1a49f --- /dev/null +++ b/include/agg_span_pattern_gray.h @@ -0,0 +1,93 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + + +#ifndef AGG_SPAN_PATTERN_GRAY_INCLUDED +#define AGG_SPAN_PATTERN_GRAY_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //=======================================================span_pattern_gray + template<class Source> class span_pattern_gray + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + + //-------------------------------------------------------------------- + span_pattern_gray() {} + span_pattern_gray(source_type& src, + unsigned offset_x, unsigned offset_y) : + m_src(&src), + m_offset_x(offset_x), + m_offset_y(offset_y), + m_alpha(color_type::base_mask) + {} + + //-------------------------------------------------------------------- + void attach(source_type& v) { m_src = &v; } + source_type& source() { return *m_src; } + const source_type& source() const { return *m_src; } + + //-------------------------------------------------------------------- + void offset_x(unsigned v) { m_offset_x = v; } + void offset_y(unsigned v) { m_offset_y = v; } + unsigned offset_x() const { return m_offset_x; } + unsigned offset_y() const { return m_offset_y; } + void alpha(value_type v) { m_alpha = v; } + value_type alpha() const { return m_alpha; } + + //-------------------------------------------------------------------- + void prepare() {} + void generate(color_type* span, int x, int y, unsigned len) + { + x += m_offset_x; + y += m_offset_y; + const value_type* p = (const value_type*)m_src->span(x, y, len); + do + { + span->v = *p; + span->a = m_alpha; + p = m_src->next_x(); + ++span; + } + while(--len); + } + + private: + source_type* m_src; + unsigned m_offset_x; + unsigned m_offset_y; + value_type m_alpha; + + }; + +} + +#endif + diff --git a/include/agg_span_pattern_rgb.h b/include/agg_span_pattern_rgb.h new file mode 100644 index 0000000..4850508 --- /dev/null +++ b/include/agg_span_pattern_rgb.h @@ -0,0 +1,96 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + + +#ifndef AGG_SPAN_PATTERN_RGB_INCLUDED +#define AGG_SPAN_PATTERN_RGB_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //========================================================span_pattern_rgb + template<class Source> class span_pattern_rgb + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + + //-------------------------------------------------------------------- + span_pattern_rgb() {} + span_pattern_rgb(source_type& src, + unsigned offset_x, unsigned offset_y) : + m_src(&src), + m_offset_x(offset_x), + m_offset_y(offset_y), + m_alpha(color_type::base_mask) + {} + + //-------------------------------------------------------------------- + void attach(source_type& v) { m_src = &v; } + source_type& source() { return *m_src; } + const source_type& source() const { return *m_src; } + + //-------------------------------------------------------------------- + void offset_x(unsigned v) { m_offset_x = v; } + void offset_y(unsigned v) { m_offset_y = v; } + unsigned offset_x() const { return m_offset_x; } + unsigned offset_y() const { return m_offset_y; } + void alpha(value_type v) { m_alpha = v; } + value_type alpha() const { return m_alpha; } + + //-------------------------------------------------------------------- + void prepare() {} + void generate(color_type* span, int x, int y, unsigned len) + { + x += m_offset_x; + y += m_offset_y; + const value_type* p = (const value_type*)m_src->span(x, y, len); + do + { + span->r = p[order_type::R]; + span->g = p[order_type::G]; + span->b = p[order_type::B]; + span->a = m_alpha; + p = m_src->next_x(); + ++span; + } + while(--len); + } + + private: + source_type* m_src; + unsigned m_offset_x; + unsigned m_offset_y; + value_type m_alpha; + + }; + +} + +#endif + diff --git a/include/agg_span_pattern_rgba.h b/include/agg_span_pattern_rgba.h new file mode 100644 index 0000000..d47d2a6 --- /dev/null +++ b/include/agg_span_pattern_rgba.h @@ -0,0 +1,94 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Adaptation for high precision colors has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + + +#ifndef AGG_SPAN_PATTERN_RGBA_INCLUDED +#define AGG_SPAN_PATTERN_RGBA_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //======================================================span_pattern_rgba + template<class Source> class span_pattern_rgba + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + + //-------------------------------------------------------------------- + span_pattern_rgba() {} + span_pattern_rgba(source_type& src, + unsigned offset_x, unsigned offset_y) : + m_src(&src), + m_offset_x(offset_x), + m_offset_y(offset_y) + {} + + //-------------------------------------------------------------------- + void attach(source_type& v) { m_src = &v; } + source_type& source() { return *m_src; } + const source_type& source() const { return *m_src; } + + //-------------------------------------------------------------------- + void offset_x(unsigned v) { m_offset_x = v; } + void offset_y(unsigned v) { m_offset_y = v; } + unsigned offset_x() const { return m_offset_x; } + unsigned offset_y() const { return m_offset_y; } + void alpha(value_type) {} + value_type alpha() const { return 0; } + + //-------------------------------------------------------------------- + void prepare() {} + void generate(color_type* span, int x, int y, unsigned len) + { + x += m_offset_x; + y += m_offset_y; + const value_type* p = (const value_type*)m_src->span(x, y, len); + do + { + span->r = p[order_type::R]; + span->g = p[order_type::G]; + span->b = p[order_type::B]; + span->a = p[order_type::A]; + p = (const value_type*)m_src->next_x(); + ++span; + } + while(--len); + } + + private: + source_type* m_src; + unsigned m_offset_x; + unsigned m_offset_y; + + }; + +} + +#endif + diff --git a/include/agg_span_solid.h b/include/agg_span_solid.h new file mode 100644 index 0000000..ee46df9 --- /dev/null +++ b/include/agg_span_solid.h @@ -0,0 +1,53 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// span_solid_rgba8 +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SPAN_SOLID_INCLUDED +#define AGG_SPAN_SOLID_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //--------------------------------------------------------------span_solid + template<class ColorT> class span_solid + { + public: + typedef ColorT color_type; + + //-------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + do { *span++ = m_color; } while(--len); + } + + private: + color_type m_color; + }; + + +} + +#endif diff --git a/include/agg_span_subdiv_adaptor.h b/include/agg_span_subdiv_adaptor.h new file mode 100644 index 0000000..b5b855e --- /dev/null +++ b/include/agg_span_subdiv_adaptor.h @@ -0,0 +1,141 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +#ifndef AGG_SPAN_SUBDIV_ADAPTOR_INCLUDED +#define AGG_SPAN_SUBDIV_ADAPTOR_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //=================================================span_subdiv_adaptor + template<class Interpolator, unsigned SubpixelShift = 8> + class span_subdiv_adaptor + { + public: + typedef Interpolator interpolator_type; + typedef typename interpolator_type::trans_type trans_type; + + enum sublixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + + //---------------------------------------------------------------- + span_subdiv_adaptor() : + m_subdiv_shift(4), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1) {} + + span_subdiv_adaptor(interpolator_type& interpolator, + unsigned subdiv_shift = 4) : + m_subdiv_shift(subdiv_shift), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1), + m_interpolator(&interpolator) {} + + span_subdiv_adaptor(interpolator_type& interpolator, + double x, double y, unsigned len, + unsigned subdiv_shift = 4) : + m_subdiv_shift(subdiv_shift), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1), + m_interpolator(&interpolator) + { + begin(x, y, len); + } + + + //---------------------------------------------------------------- + const interpolator_type& interpolator() const { return *m_interpolator; } + void interpolator(interpolator_type& intr) { m_interpolator = &intr; } + + //---------------------------------------------------------------- + const trans_type& transformer() const + { + return *m_interpolator->transformer(); + } + void transformer(const trans_type& trans) + { + m_interpolator->transformer(trans); + } + + //---------------------------------------------------------------- + unsigned subdiv_shift() const { return m_subdiv_shift; } + void subdiv_shift(unsigned shift) + { + m_subdiv_shift = shift; + m_subdiv_size = 1 << m_subdiv_shift; + m_subdiv_mask = m_subdiv_size - 1; + } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned len) + { + m_pos = 1; + m_src_x = iround(x * subpixel_scale) + subpixel_scale; + m_src_y = y; + m_len = len; + if(len > m_subdiv_size) len = m_subdiv_size; + m_interpolator->begin(x, y, len); + } + + //---------------------------------------------------------------- + void operator++() + { + ++(*m_interpolator); + if(m_pos >= m_subdiv_size) + { + unsigned len = m_len; + if(len > m_subdiv_size) len = m_subdiv_size; + m_interpolator->resynchronize(double(m_src_x) / double(subpixel_scale) + len, + m_src_y, + len); + m_pos = 0; + } + m_src_x += subpixel_scale; + ++m_pos; + --m_len; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + m_interpolator->coordinates(x, y); + } + + //---------------------------------------------------------------- + void local_scale(int* x, int* y) const + { + m_interpolator->local_scale(x, y); + } + + + private: + unsigned m_subdiv_shift; + unsigned m_subdiv_size; + unsigned m_subdiv_mask; + interpolator_type* m_interpolator; + int m_src_x; + double m_src_y; + unsigned m_pos; + unsigned m_len; + }; + +} + +#endif diff --git a/include/agg_trans_affine.h b/include/agg_trans_affine.h new file mode 100644 index 0000000..b3cc1b0 --- /dev/null +++ b/include/agg_trans_affine.h @@ -0,0 +1,518 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Affine transformation classes. +// +//---------------------------------------------------------------------------- +#ifndef AGG_TRANS_AFFINE_INCLUDED +#define AGG_TRANS_AFFINE_INCLUDED + +#include <cmath> +#include "agg_basics.h" + +namespace agg +{ + const double affine_epsilon = 1e-14; + + //============================================================trans_affine + // + // See Implementation agg_trans_affine.cpp + // + // Affine transformation are linear transformations in Cartesian coordinates + // (strictly speaking not only in Cartesian, but for the beginning we will + // think so). They are rotation, scaling, translation and skewing. + // After any affine transformation a line segment remains a line segment + // and it will never become a curve. + // + // There will be no math about matrix calculations, since it has been + // described many times. Ask yourself a very simple question: + // "why do we need to understand and use some matrix stuff instead of just + // rotating, scaling and so on". The answers are: + // + // 1. Any combination of transformations can be done by only 4 multiplications + // and 4 additions in floating point. + // 2. One matrix transformation is equivalent to the number of consecutive + // discrete transformations, i.e. the matrix "accumulates" all transformations + // in the order of their settings. Suppose we have 4 transformations: + // * rotate by 30 degrees, + // * scale X to 2.0, + // * scale Y to 1.5, + // * move to (100, 100). + // The result will depend on the order of these transformations, + // and the advantage of matrix is that the sequence of discret calls: + // rotate(30), scaleX(2.0), scaleY(1.5), move(100,100) + // will have exactly the same result as the following matrix transformations: + // + // affine_matrix m; + // m *= rotate_matrix(30); + // m *= scaleX_matrix(2.0); + // m *= scaleY_matrix(1.5); + // m *= move_matrix(100,100); + // + // m.transform_my_point_at_last(x, y); + // + // What is the good of it? In real life we will set-up the matrix only once + // and then transform many points, let alone the convenience to set any + // combination of transformations. + // + // So, how to use it? Very easy - literally as it's shown above. Not quite, + // let us write a correct example: + // + // agg::trans_affine m; + // m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); + // m *= agg::trans_affine_scaling(2.0, 1.5); + // m *= agg::trans_affine_translation(100.0, 100.0); + // m.transform(&x, &y); + // + // The affine matrix is all you need to perform any linear transformation, + // but all transformations have origin point (0,0). It means that we need to + // use 2 translations if we want to rotate someting around (100,100): + // + // m *= agg::trans_affine_translation(-100.0, -100.0); // move to (0,0) + // m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); // rotate + // m *= agg::trans_affine_translation(100.0, 100.0); // move back to (100,100) + //---------------------------------------------------------------------- + struct trans_affine + { + double sx, shy, shx, sy, tx, ty; + + //------------------------------------------ Construction + // Identity matrix + trans_affine() : + sx(1.0), shy(0.0), shx(0.0), sy(1.0), tx(0.0), ty(0.0) + {} + + // Custom matrix. Usually used in derived classes + trans_affine(double v0, double v1, double v2, + double v3, double v4, double v5) : + sx(v0), shy(v1), shx(v2), sy(v3), tx(v4), ty(v5) + {} + + // Custom matrix from m[6] + explicit trans_affine(const double* m) : + sx(m[0]), shy(m[1]), shx(m[2]), sy(m[3]), tx(m[4]), ty(m[5]) + {} + + // Rectangle to a parallelogram. + trans_affine(double x1, double y1, double x2, double y2, + const double* parl) + { + rect_to_parl(x1, y1, x2, y2, parl); + } + + // Parallelogram to a rectangle. + trans_affine(const double* parl, + double x1, double y1, double x2, double y2) + { + parl_to_rect(parl, x1, y1, x2, y2); + } + + // Arbitrary parallelogram transformation. + trans_affine(const double* src, const double* dst) + { + parl_to_parl(src, dst); + } + + //---------------------------------- Parellelogram transformations + // transform a parallelogram to another one. Src and dst are + // pointers to arrays of three points (double[6], x1,y1,...) that + // identify three corners of the parallelograms assuming implicit + // fourth point. The arguments are arrays of double[6] mapped + // to x1,y1, x2,y2, x3,y3 where the coordinates are: + // *-----------------* + // / (x3,y3)/ + // / / + // /(x1,y1) (x2,y2)/ + // *-----------------* + const trans_affine& parl_to_parl(const double* src, + const double* dst); + + const trans_affine& rect_to_parl(double x1, double y1, + double x2, double y2, + const double* parl); + + const trans_affine& parl_to_rect(const double* parl, + double x1, double y1, + double x2, double y2); + + + //------------------------------------------ Operations + // Reset - load an identity matrix + const trans_affine& reset(); + + // Direct transformations operations + const trans_affine& translate(double x, double y); + const trans_affine& rotate(double a); + const trans_affine& scale(double s); + const trans_affine& scale(double x, double y); + + // Multiply matrix to another one + const trans_affine& multiply(const trans_affine& m); + + // Multiply "m" to "this" and assign the result to "this" + const trans_affine& premultiply(const trans_affine& m); + + // Multiply matrix to inverse of another one + const trans_affine& multiply_inv(const trans_affine& m); + + // Multiply inverse of "m" to "this" and assign the result to "this" + const trans_affine& premultiply_inv(const trans_affine& m); + + // Invert matrix. Do not try to invert degenerate matrices, + // there's no check for validity. If you set scale to 0 and + // then try to invert matrix, expect unpredictable result. + const trans_affine& invert(); + + // Mirroring around X + const trans_affine& flip_x(); + + // Mirroring around Y + const trans_affine& flip_y(); + + //------------------------------------------- Load/Store + // Store matrix to an array [6] of double + void store_to(double* m) const + { + *m++ = sx; *m++ = shy; *m++ = shx; *m++ = sy; *m++ = tx; *m++ = ty; + } + + // Load matrix from an array [6] of double + const trans_affine& load_from(const double* m) + { + sx = *m++; shy = *m++; shx = *m++; sy = *m++; tx = *m++; ty = *m++; + return *this; + } + + //------------------------------------------- Operators + + // Multiply the matrix by another one + const trans_affine& operator *= (const trans_affine& m) + { + return multiply(m); + } + + // Multiply the matrix by inverse of another one + const trans_affine& operator /= (const trans_affine& m) + { + return multiply_inv(m); + } + + // Multiply the matrix by another one and return + // the result in a separete matrix. + trans_affine operator * (const trans_affine& m) const + { + return trans_affine(*this).multiply(m); + } + + // Multiply the matrix by inverse of another one + // and return the result in a separete matrix. + trans_affine operator / (const trans_affine& m) const + { + return trans_affine(*this).multiply_inv(m); + } + + // Calculate and return the inverse matrix + trans_affine operator ~ () const + { + trans_affine ret = *this; + return ret.invert(); + } + + // Equal operator with default epsilon + bool operator == (const trans_affine& m) const + { + return is_equal(m, affine_epsilon); + } + + // Not Equal operator with default epsilon + bool operator != (const trans_affine& m) const + { + return !is_equal(m, affine_epsilon); + } + + //-------------------------------------------- Transformations + // Direct transformation of x and y + void transform(double* x, double* y) const; + + // Direct transformation of x and y, 2x2 matrix only, no translation + void transform_2x2(double* x, double* y) const; + + // Inverse transformation of x and y. It works slower than the + // direct transformation. For massive operations it's better to + // invert() the matrix and then use direct transformations. + void inverse_transform(double* x, double* y) const; + + //-------------------------------------------- Auxiliary + // Calculate the determinant of matrix + double determinant() const + { + return sx * sy - shy * shx; + } + + // Calculate the reciprocal of the determinant + double determinant_reciprocal() const + { + return 1.0 / (sx * sy - shy * shx); + } + + // Get the average scale (by X and Y). + // Basically used to calculate the approximation_scale when + // decomposinting curves into line segments. + double scale() const; + + // Check to see if the matrix is not degenerate + bool is_valid(double epsilon = affine_epsilon) const; + + // Check to see if it's an identity matrix + bool is_identity(double epsilon = affine_epsilon) const; + + // Check to see if two matrices are equal + bool is_equal(const trans_affine& m, double epsilon = affine_epsilon) const; + + // Determine the major parameters. Use with caution considering + // possible degenerate cases. + double rotation() const; + void translation(double* dx, double* dy) const; + void scaling(double* x, double* y) const; + void scaling_abs(double* x, double* y) const; + }; + + //------------------------------------------------------------------------ + inline void trans_affine::transform(double* x, double* y) const + { + double tmp = *x; + *x = tmp * sx + *y * shx + tx; + *y = tmp * shy + *y * sy + ty; + } + + //------------------------------------------------------------------------ + inline void trans_affine::transform_2x2(double* x, double* y) const + { + double tmp = *x; + *x = tmp * sx + *y * shx; + *y = tmp * shy + *y * sy; + } + + //------------------------------------------------------------------------ + inline void trans_affine::inverse_transform(double* x, double* y) const + { + double d = determinant_reciprocal(); + double a = (*x - tx) * d; + double b = (*y - ty) * d; + *x = a * sy - b * shx; + *y = b * sx - a * shy; + } + + //------------------------------------------------------------------------ + inline double trans_affine::scale() const + { + double x = 0.70710678118654752440 * sx + 0.70710678118654752440 * shx; + double y = 0.70710678118654752440 * shy + 0.70710678118654752440 * sy; + return std::sqrt(x*x + y*y); + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::translate(double x, double y) + { + tx += x; + ty += y; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::rotate(double a) + { + double ca = std::cos(a); + double sa = std::sin(a); + double t0 = sx * ca - shy * sa; + double t2 = shx * ca - sy * sa; + double t4 = tx * ca - ty * sa; + shy = sx * sa + shy * ca; + sy = shx * sa + sy * ca; + ty = tx * sa + ty * ca; + sx = t0; + shx = t2; + tx = t4; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::scale(double x, double y) + { + double mm0 = x; // Possible hint for the optimizer + double mm3 = y; + sx *= mm0; + shx *= mm0; + tx *= mm0; + shy *= mm3; + sy *= mm3; + ty *= mm3; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::scale(double s) + { + double m = s; // Possible hint for the optimizer + sx *= m; + shx *= m; + tx *= m; + shy *= m; + sy *= m; + ty *= m; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::premultiply(const trans_affine& m) + { + trans_affine t = m; + return *this = t.multiply(*this); + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::multiply_inv(const trans_affine& m) + { + trans_affine t = m; + t.invert(); + return multiply(t); + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::premultiply_inv(const trans_affine& m) + { + trans_affine t = m; + t.invert(); + return *this = t.multiply(*this); + } + + //------------------------------------------------------------------------ + inline void trans_affine::scaling_abs(double* x, double* y) const + { + // Used to calculate scaling coefficients in image resampling. + // When there is considerable shear this method gives us much + // better estimation than just sx, sy. + *x = std::sqrt(sx * sx + shx * shx); + *y = std::sqrt(shy * shy + sy * sy); + } + + //====================================================trans_affine_rotation + // Rotation matrix. sin() and cos() are calculated twice for the same angle. + // There's no harm because the performance of sin()/cos() is very good on all + // modern processors. Besides, this operation is not going to be invoked too + // often. + class trans_affine_rotation : public trans_affine + { + public: + trans_affine_rotation(double a) : + trans_affine(std::cos(a), std::sin(a), -std::sin(a), std::cos(a), 0.0, 0.0) + {} + }; + + //====================================================trans_affine_scaling + // Scaling matrix. x, y - scale coefficients by X and Y respectively + class trans_affine_scaling : public trans_affine + { + public: + trans_affine_scaling(double x, double y) : + trans_affine(x, 0.0, 0.0, y, 0.0, 0.0) + {} + + trans_affine_scaling(double s) : + trans_affine(s, 0.0, 0.0, s, 0.0, 0.0) + {} + }; + + //================================================trans_affine_translation + // Translation matrix + class trans_affine_translation : public trans_affine + { + public: + trans_affine_translation(double x, double y) : + trans_affine(1.0, 0.0, 0.0, 1.0, x, y) + {} + }; + + //====================================================trans_affine_skewing + // Sckewing (shear) matrix + class trans_affine_skewing : public trans_affine + { + public: + trans_affine_skewing(double x, double y) : + trans_affine(1.0, std::tan(y), std::tan(x), 1.0, 0.0, 0.0) + {} + }; + + + //===============================================trans_affine_line_segment + // Rotate, Scale and Translate, associating 0...dist with line segment + // x1,y1,x2,y2 + class trans_affine_line_segment : public trans_affine + { + public: + trans_affine_line_segment(double x1, double y1, double x2, double y2, + double dist) + { + double dx = x2 - x1; + double dy = y2 - y1; + if(dist > 0.0) + { + multiply(trans_affine_scaling(std::sqrt(dx * dx + dy * dy) / dist)); + } + multiply(trans_affine_rotation(std::atan2(dy, dx))); + multiply(trans_affine_translation(x1, y1)); + } + }; + + + //============================================trans_affine_reflection_unit + // Reflection matrix. Reflect coordinates across the line through + // the origin containing the unit vector (ux, uy). + // Contributed by John Horigan + class trans_affine_reflection_unit : public trans_affine + { + public: + trans_affine_reflection_unit(double ux, double uy) : + trans_affine(2.0 * ux * ux - 1.0, + 2.0 * ux * uy, + 2.0 * ux * uy, + 2.0 * uy * uy - 1.0, + 0.0, 0.0) + {} + }; + + + //=================================================trans_affine_reflection + // Reflection matrix. Reflect coordinates across the line through + // the origin at the angle a or containing the non-unit vector (x, y). + // Contributed by John Horigan + class trans_affine_reflection : public trans_affine_reflection_unit + { + public: + trans_affine_reflection(double a) : + trans_affine_reflection_unit(std::cos(a), std::sin(a)) + {} + + + trans_affine_reflection(double x, double y) : + trans_affine_reflection_unit(x / std::sqrt(x * x + y * y), y / std::sqrt(x * x + y * y)) + {} + }; + +} + + +#endif + diff --git a/include/agg_trans_bilinear.h b/include/agg_trans_bilinear.h new file mode 100644 index 0000000..f3ab596 --- /dev/null +++ b/include/agg_trans_bilinear.h @@ -0,0 +1,166 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Bilinear 2D transformations +// +//---------------------------------------------------------------------------- +#ifndef AGG_TRANS_BILINEAR_INCLUDED +#define AGG_TRANS_BILINEAR_INCLUDED + +#include "agg_basics.h" +#include "agg_simul_eq.h" + +namespace agg +{ + + //==========================================================trans_bilinear + class trans_bilinear + { + public: + //-------------------------------------------------------------------- + trans_bilinear() : m_valid(false) {} + + //-------------------------------------------------------------------- + // Arbitrary quadrangle transformations + trans_bilinear(const double* src, const double* dst) + { + quad_to_quad(src, dst); + } + + + //-------------------------------------------------------------------- + // Direct transformations + trans_bilinear(double x1, double y1, double x2, double y2, + const double* quad) + { + rect_to_quad(x1, y1, x2, y2, quad); + } + + + //-------------------------------------------------------------------- + // Reverse transformations + trans_bilinear(const double* quad, + double x1, double y1, double x2, double y2) + { + quad_to_rect(quad, x1, y1, x2, y2); + } + + + //-------------------------------------------------------------------- + // Set the transformations using two arbitrary quadrangles. + void quad_to_quad(const double* src, const double* dst) + { + double left[4][4]; + double right[4][2]; + + unsigned i; + for(i = 0; i < 4; i++) + { + unsigned ix = i * 2; + unsigned iy = ix + 1; + left[i][0] = 1.0; + left[i][1] = src[ix] * src[iy]; + left[i][2] = src[ix]; + left[i][3] = src[iy]; + + right[i][0] = dst[ix]; + right[i][1] = dst[iy]; + } + m_valid = simul_eq<4, 2>::solve(left, right, m_mtx); + } + + + //-------------------------------------------------------------------- + // Set the direct transformations, i.e., rectangle -> quadrangle + void rect_to_quad(double x1, double y1, double x2, double y2, + const double* quad) + { + double src[8]; + src[0] = src[6] = x1; + src[2] = src[4] = x2; + src[1] = src[3] = y1; + src[5] = src[7] = y2; + quad_to_quad(src, quad); + } + + + //-------------------------------------------------------------------- + // Set the reverse transformations, i.e., quadrangle -> rectangle + void quad_to_rect(const double* quad, + double x1, double y1, double x2, double y2) + { + double dst[8]; + dst[0] = dst[6] = x1; + dst[2] = dst[4] = x2; + dst[1] = dst[3] = y1; + dst[5] = dst[7] = y2; + quad_to_quad(quad, dst); + } + + //-------------------------------------------------------------------- + // Check if the equations were solved successfully + bool is_valid() const { return m_valid; } + + //-------------------------------------------------------------------- + // Transform a point (x, y) + void transform(double* x, double* y) const + { + double tx = *x; + double ty = *y; + double xy = tx * ty; + *x = m_mtx[0][0] + m_mtx[1][0] * xy + m_mtx[2][0] * tx + m_mtx[3][0] * ty; + *y = m_mtx[0][1] + m_mtx[1][1] * xy + m_mtx[2][1] * tx + m_mtx[3][1] * ty; + } + + + //-------------------------------------------------------------------- + class iterator_x + { + double inc_x; + double inc_y; + + public: + double x; + double y; + + iterator_x() {} + iterator_x(double tx, double ty, double step, const double m[4][2]) : + inc_x(m[1][0] * step * ty + m[2][0] * step), + inc_y(m[1][1] * step * ty + m[2][1] * step), + x(m[0][0] + m[1][0] * tx * ty + m[2][0] * tx + m[3][0] * ty), + y(m[0][1] + m[1][1] * tx * ty + m[2][1] * tx + m[3][1] * ty) + { + } + + void operator ++ () + { + x += inc_x; + y += inc_y; + } + }; + + iterator_x begin(double x, double y, double step) const + { + return iterator_x(x, y, step, m_mtx); + } + + private: + double m_mtx[4][2]; + bool m_valid; + }; + +} + +#endif diff --git a/include/agg_trans_double_path.h b/include/agg_trans_double_path.h new file mode 100644 index 0000000..c645a7f --- /dev/null +++ b/include/agg_trans_double_path.h @@ -0,0 +1,131 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_TRANS_DOUBLE_PATH_INCLUDED +#define AGG_TRANS_DOUBLE_PATH_INCLUDED + +#include "agg_basics.h" +#include "agg_vertex_sequence.h" + +namespace agg +{ + + // See also: agg_trans_double_path.cpp + // + //-------------------------------------------------------trans_double_path + class trans_double_path + { + enum status_e + { + initial, + making_path, + ready + }; + + public: + typedef vertex_sequence<vertex_dist, 6> vertex_storage; + + trans_double_path(); + + //-------------------------------------------------------------------- + void base_length(double v) { m_base_length = v; } + double base_length() const { return m_base_length; } + + //-------------------------------------------------------------------- + void base_height(double v) { m_base_height = v; } + double base_height() const { return m_base_height; } + + //-------------------------------------------------------------------- + void preserve_x_scale(bool f) { m_preserve_x_scale = f; } + bool preserve_x_scale() const { return m_preserve_x_scale; } + + //-------------------------------------------------------------------- + void reset(); + void move_to1(double x, double y); + void line_to1(double x, double y); + void move_to2(double x, double y); + void line_to2(double x, double y); + void finalize_paths(); + + //-------------------------------------------------------------------- + template<class VertexSource1, class VertexSource2> + void add_paths(VertexSource1& vs1, VertexSource2& vs2, + unsigned path1_id=0, unsigned path2_id=0) + { + double x; + double y; + + unsigned cmd; + + vs1.rewind(path1_id); + while(!is_stop(cmd = vs1.vertex(&x, &y))) + { + if(is_move_to(cmd)) + { + move_to1(x, y); + } + else + { + if(is_vertex(cmd)) + { + line_to1(x, y); + } + } + } + + vs2.rewind(path2_id); + while(!is_stop(cmd = vs2.vertex(&x, &y))) + { + if(is_move_to(cmd)) + { + move_to2(x, y); + } + else + { + if(is_vertex(cmd)) + { + line_to2(x, y); + } + } + } + finalize_paths(); + } + + //-------------------------------------------------------------------- + double total_length1() const; + double total_length2() const; + void transform(double *x, double *y) const; + + private: + double finalize_path(vertex_storage& vertices); + void transform1(const vertex_storage& vertices, + double kindex, double kx, + double *x, double* y) const; + + vertex_storage m_src_vertices1; + vertex_storage m_src_vertices2; + double m_base_length; + double m_base_height; + double m_kindex1; + double m_kindex2; + status_e m_status1; + status_e m_status2; + bool m_preserve_x_scale; + }; + +} + + +#endif diff --git a/include/agg_trans_perspective.h b/include/agg_trans_perspective.h new file mode 100644 index 0000000..1c650aa --- /dev/null +++ b/include/agg_trans_perspective.h @@ -0,0 +1,732 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Perspective 2D transformations +// +//---------------------------------------------------------------------------- +#ifndef AGG_TRANS_PERSPECTIVE_INCLUDED +#define AGG_TRANS_PERSPECTIVE_INCLUDED + +#include <cmath> +#include "agg_trans_affine.h" + +namespace agg +{ + //=======================================================trans_perspective + struct trans_perspective + { + double sx, shy, w0, shx, sy, w1, tx, ty, w2; + + //------------------------------------------------------- Construction + // Identity matrix + trans_perspective() : + sx (1), shy(0), w0(0), + shx(0), sy (1), w1(0), + tx (0), ty (0), w2(1) {} + + // Custom matrix + trans_perspective(double v0, double v1, double v2, + double v3, double v4, double v5, + double v6, double v7, double v8) : + sx (v0), shy(v1), w0(v2), + shx(v3), sy (v4), w1(v5), + tx (v6), ty (v7), w2(v8) {} + + // Custom matrix from m[9] + explicit trans_perspective(const double* m) : + sx (m[0]), shy(m[1]), w0(m[2]), + shx(m[3]), sy (m[4]), w1(m[5]), + tx (m[6]), ty (m[7]), w2(m[8]) {} + + // From affine + explicit trans_perspective(const trans_affine& a) : + sx (a.sx ), shy(a.shy), w0(0), + shx(a.shx), sy (a.sy ), w1(0), + tx (a.tx ), ty (a.ty ), w2(1) {} + + // Rectangle to quadrilateral + trans_perspective(double x1, double y1, double x2, double y2, + const double* quad); + + // Quadrilateral to rectangle + trans_perspective(const double* quad, + double x1, double y1, double x2, double y2); + + // Arbitrary quadrilateral transformations + trans_perspective(const double* src, const double* dst); + + //-------------------------------------- Quadrilateral transformations + // The arguments are double[8] that are mapped to quadrilaterals: + // x1,y1, x2,y2, x3,y3, x4,y4 + bool quad_to_quad(const double* qs, const double* qd); + + bool rect_to_quad(double x1, double y1, + double x2, double y2, + const double* q); + + bool quad_to_rect(const double* q, + double x1, double y1, + double x2, double y2); + + // Map square (0,0,1,1) to the quadrilateral and vice versa + bool square_to_quad(const double* q); + bool quad_to_square(const double* q); + + + //--------------------------------------------------------- Operations + // Reset - load an identity matrix + const trans_perspective& reset(); + + // Invert matrix. Returns false in degenerate case + bool invert(); + + // Direct transformations operations + const trans_perspective& translate(double x, double y); + const trans_perspective& rotate(double a); + const trans_perspective& scale(double s); + const trans_perspective& scale(double x, double y); + + // Multiply the matrix by another one + const trans_perspective& multiply(const trans_perspective& m); + + // Multiply "m" by "this" and assign the result to "this" + const trans_perspective& premultiply(const trans_perspective& m); + + // Multiply matrix to inverse of another one + const trans_perspective& multiply_inv(const trans_perspective& m); + + // Multiply inverse of "m" by "this" and assign the result to "this" + const trans_perspective& premultiply_inv(const trans_perspective& m); + + // Multiply the matrix by another one + const trans_perspective& multiply(const trans_affine& m); + + // Multiply "m" by "this" and assign the result to "this" + const trans_perspective& premultiply(const trans_affine& m); + + // Multiply the matrix by inverse of another one + const trans_perspective& multiply_inv(const trans_affine& m); + + // Multiply inverse of "m" by "this" and assign the result to "this" + const trans_perspective& premultiply_inv(const trans_affine& m); + + //--------------------------------------------------------- Load/Store + void store_to(double* m) const; + const trans_perspective& load_from(const double* m); + + //---------------------------------------------------------- Operators + // Multiply the matrix by another one + const trans_perspective& operator *= (const trans_perspective& m) + { + return multiply(m); + } + const trans_perspective& operator *= (const trans_affine& m) + { + return multiply(m); + } + + // Multiply the matrix by inverse of another one + const trans_perspective& operator /= (const trans_perspective& m) + { + return multiply_inv(m); + } + const trans_perspective& operator /= (const trans_affine& m) + { + return multiply_inv(m); + } + + // Multiply the matrix by another one and return + // the result in a separete matrix. + trans_perspective operator * (const trans_perspective& m) const + { + return trans_perspective(*this).multiply(m); + } + trans_perspective operator * (const trans_affine& m) const + { + return trans_perspective(*this).multiply(m); + } + + // Multiply the matrix by inverse of another one + // and return the result in a separete matrix. + trans_perspective operator / (const trans_perspective& m) const + { + return trans_perspective(*this).multiply_inv(m); + } + trans_perspective operator / (const trans_affine& m) const + { + return trans_perspective(*this).multiply_inv(m); + } + + // Calculate and return the inverse matrix + trans_perspective operator ~ () const + { + trans_perspective ret = *this; + ret.invert(); + return ret; + } + + // Equal operator with default epsilon + bool operator == (const trans_perspective& m) const + { + return is_equal(m, affine_epsilon); + } + + // Not Equal operator with default epsilon + bool operator != (const trans_perspective& m) const + { + return !is_equal(m, affine_epsilon); + } + + //---------------------------------------------------- Transformations + // Direct transformation of x and y + void transform(double* x, double* y) const; + + // Direct transformation of x and y, affine part only + void transform_affine(double* x, double* y) const; + + // Direct transformation of x and y, 2x2 matrix only, no translation + void transform_2x2(double* x, double* y) const; + + // Inverse transformation of x and y. It works slow because + // it explicitly inverts the matrix on every call. For massive + // operations it's better to invert() the matrix and then use + // direct transformations. + void inverse_transform(double* x, double* y) const; + + + //---------------------------------------------------------- Auxiliary + const trans_perspective& from_affine(const trans_affine& a); + double determinant() const; + double determinant_reciprocal() const; + + bool is_valid(double epsilon = affine_epsilon) const; + bool is_identity(double epsilon = affine_epsilon) const; + bool is_equal(const trans_perspective& m, + double epsilon = affine_epsilon) const; + + // Determine the major affine parameters. Use with caution + // considering possible degenerate cases. + double scale() const; + double rotation() const; + void translation(double* dx, double* dy) const; + void scaling(double* x, double* y) const; + void scaling_abs(double* x, double* y) const; + + + + //-------------------------------------------------------------------- + class iterator_x + { + double den; + double den_step; + double nom_x; + double nom_x_step; + double nom_y; + double nom_y_step; + + public: + double x; + double y; + + iterator_x() {} + iterator_x(double px, double py, double step, const trans_perspective& m) : + den(px * m.w0 + py * m.w1 + m.w2), + den_step(m.w0 * step), + nom_x(px * m.sx + py * m.shx + m.tx), + nom_x_step(step * m.sx), + nom_y(px * m.shy + py * m.sy + m.ty), + nom_y_step(step * m.shy), + x(nom_x / den), + y(nom_y / den) + {} + + void operator ++ () + { + den += den_step; + nom_x += nom_x_step; + nom_y += nom_y_step; + double d = 1.0 / den; + x = nom_x * d; + y = nom_y * d; + } + }; + + //-------------------------------------------------------------------- + iterator_x begin(double x, double y, double step) const + { + return iterator_x(x, y, step, *this); + } + }; + + + + + + + + + + + + + + + //------------------------------------------------------------------------ + inline bool trans_perspective::square_to_quad(const double* q) + { + double dx = q[0] - q[2] + q[4] - q[6]; + double dy = q[1] - q[3] + q[5] - q[7]; + if(dx == 0.0 && dy == 0.0) + { + // Affine case (parallelogram) + //--------------- + sx = q[2] - q[0]; + shy = q[3] - q[1]; + w0 = 0.0; + shx = q[4] - q[2]; + sy = q[5] - q[3]; + w1 = 0.0; + tx = q[0]; + ty = q[1]; + w2 = 1.0; + } + else + { + double dx1 = q[2] - q[4]; + double dy1 = q[3] - q[5]; + double dx2 = q[6] - q[4]; + double dy2 = q[7] - q[5]; + double den = dx1 * dy2 - dx2 * dy1; + if(den == 0.0) + { + // Singular case + //--------------- + sx = shy = w0 = shx = sy = w1 = tx = ty = w2 = 0.0; + return false; + } + // General case + //--------------- + double u = (dx * dy2 - dy * dx2) / den; + double v = (dy * dx1 - dx * dy1) / den; + sx = q[2] - q[0] + u * q[2]; + shy = q[3] - q[1] + u * q[3]; + w0 = u; + shx = q[6] - q[0] + v * q[6]; + sy = q[7] - q[1] + v * q[7]; + w1 = v; + tx = q[0]; + ty = q[1]; + w2 = 1.0; + } + return true; + } + + //------------------------------------------------------------------------ + inline bool trans_perspective::invert() + { + double d0 = sy * w2 - w1 * ty; + double d1 = w0 * ty - shy * w2; + double d2 = shy * w1 - w0 * sy; + double d = sx * d0 + shx * d1 + tx * d2; + if(d == 0.0) + { + sx = shy = w0 = shx = sy = w1 = tx = ty = w2 = 0.0; + return false; + } + d = 1.0 / d; + trans_perspective a = *this; + sx = d * d0; + shy = d * d1; + w0 = d * d2; + shx = d * (a.w1 *a.tx - a.shx*a.w2); + sy = d * (a.sx *a.w2 - a.w0 *a.tx); + w1 = d * (a.w0 *a.shx - a.sx *a.w1); + tx = d * (a.shx*a.ty - a.sy *a.tx); + ty = d * (a.shy*a.tx - a.sx *a.ty); + w2 = d * (a.sx *a.sy - a.shy*a.shx); + return true; + } + + //------------------------------------------------------------------------ + inline bool trans_perspective::quad_to_square(const double* q) + { + if(!square_to_quad(q)) return false; + invert(); + return true; + } + + //------------------------------------------------------------------------ + inline bool trans_perspective::quad_to_quad(const double* qs, + const double* qd) + { + trans_perspective p; + if(! quad_to_square(qs)) return false; + if(!p.square_to_quad(qd)) return false; + multiply(p); + return true; + } + + //------------------------------------------------------------------------ + inline bool trans_perspective::rect_to_quad(double x1, double y1, + double x2, double y2, + const double* q) + { + double r[8]; + r[0] = r[6] = x1; + r[2] = r[4] = x2; + r[1] = r[3] = y1; + r[5] = r[7] = y2; + return quad_to_quad(r, q); + } + + //------------------------------------------------------------------------ + inline bool trans_perspective::quad_to_rect(const double* q, + double x1, double y1, + double x2, double y2) + { + double r[8]; + r[0] = r[6] = x1; + r[2] = r[4] = x2; + r[1] = r[3] = y1; + r[5] = r[7] = y2; + return quad_to_quad(q, r); + } + + //------------------------------------------------------------------------ + inline trans_perspective::trans_perspective(double x1, double y1, + double x2, double y2, + const double* quad) + { + rect_to_quad(x1, y1, x2, y2, quad); + } + + //------------------------------------------------------------------------ + inline trans_perspective::trans_perspective(const double* quad, + double x1, double y1, + double x2, double y2) + { + quad_to_rect(quad, x1, y1, x2, y2); + } + + //------------------------------------------------------------------------ + inline trans_perspective::trans_perspective(const double* src, + const double* dst) + { + quad_to_quad(src, dst); + } + + //------------------------------------------------------------------------ + inline const trans_perspective& trans_perspective::reset() + { + sx = 1; shy = 0; w0 = 0; + shx = 0; sy = 1; w1 = 0; + tx = 0; ty = 0; w2 = 1; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_perspective& + trans_perspective::multiply(const trans_perspective& a) + { + trans_perspective b = *this; + sx = a.sx *b.sx + a.shx*b.shy + a.tx*b.w0; + shx = a.sx *b.shx + a.shx*b.sy + a.tx*b.w1; + tx = a.sx *b.tx + a.shx*b.ty + a.tx*b.w2; + shy = a.shy*b.sx + a.sy *b.shy + a.ty*b.w0; + sy = a.shy*b.shx + a.sy *b.sy + a.ty*b.w1; + ty = a.shy*b.tx + a.sy *b.ty + a.ty*b.w2; + w0 = a.w0 *b.sx + a.w1 *b.shy + a.w2*b.w0; + w1 = a.w0 *b.shx + a.w1 *b.sy + a.w2*b.w1; + w2 = a.w0 *b.tx + a.w1 *b.ty + a.w2*b.w2; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_perspective& + trans_perspective::multiply(const trans_affine& a) + { + trans_perspective b = *this; + sx = a.sx *b.sx + a.shx*b.shy + a.tx*b.w0; + shx = a.sx *b.shx + a.shx*b.sy + a.tx*b.w1; + tx = a.sx *b.tx + a.shx*b.ty + a.tx*b.w2; + shy = a.shy*b.sx + a.sy *b.shy + a.ty*b.w0; + sy = a.shy*b.shx + a.sy *b.sy + a.ty*b.w1; + ty = a.shy*b.tx + a.sy *b.ty + a.ty*b.w2; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_perspective& + trans_perspective::premultiply(const trans_perspective& b) + { + trans_perspective a = *this; + sx = a.sx *b.sx + a.shx*b.shy + a.tx*b.w0; + shx = a.sx *b.shx + a.shx*b.sy + a.tx*b.w1; + tx = a.sx *b.tx + a.shx*b.ty + a.tx*b.w2; + shy = a.shy*b.sx + a.sy *b.shy + a.ty*b.w0; + sy = a.shy*b.shx + a.sy *b.sy + a.ty*b.w1; + ty = a.shy*b.tx + a.sy *b.ty + a.ty*b.w2; + w0 = a.w0 *b.sx + a.w1 *b.shy + a.w2*b.w0; + w1 = a.w0 *b.shx + a.w1 *b.sy + a.w2*b.w1; + w2 = a.w0 *b.tx + a.w1 *b.ty + a.w2*b.w2; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_perspective& + trans_perspective::premultiply(const trans_affine& b) + { + trans_perspective a = *this; + sx = a.sx *b.sx + a.shx*b.shy; + shx = a.sx *b.shx + a.shx*b.sy; + tx = a.sx *b.tx + a.shx*b.ty + a.tx; + shy = a.shy*b.sx + a.sy *b.shy; + sy = a.shy*b.shx + a.sy *b.sy; + ty = a.shy*b.tx + a.sy *b.ty + a.ty; + w0 = a.w0 *b.sx + a.w1 *b.shy; + w1 = a.w0 *b.shx + a.w1 *b.sy; + w2 = a.w0 *b.tx + a.w1 *b.ty + a.w2; + return *this; + } + + //------------------------------------------------------------------------ + const trans_perspective& + trans_perspective::multiply_inv(const trans_perspective& m) + { + trans_perspective t = m; + t.invert(); + return multiply(t); + } + + //------------------------------------------------------------------------ + const trans_perspective& + trans_perspective::multiply_inv(const trans_affine& m) + { + trans_affine t = m; + t.invert(); + return multiply(t); + } + + //------------------------------------------------------------------------ + const trans_perspective& + trans_perspective::premultiply_inv(const trans_perspective& m) + { + trans_perspective t = m; + t.invert(); + return *this = t.multiply(*this); + } + + //------------------------------------------------------------------------ + const trans_perspective& + trans_perspective::premultiply_inv(const trans_affine& m) + { + trans_perspective t(m); + t.invert(); + return *this = t.multiply(*this); + } + + //------------------------------------------------------------------------ + inline const trans_perspective& + trans_perspective::translate(double x, double y) + { + tx += x; + ty += y; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_perspective& trans_perspective::rotate(double a) + { + multiply(trans_affine_rotation(a)); + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_perspective& trans_perspective::scale(double s) + { + multiply(trans_affine_scaling(s)); + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_perspective& trans_perspective::scale(double x, double y) + { + multiply(trans_affine_scaling(x, y)); + return *this; + } + + //------------------------------------------------------------------------ + inline void trans_perspective::transform(double* px, double* py) const + { + double x = *px; + double y = *py; + double m = 1.0 / (x*w0 + y*w1 + w2); + *px = m * (x*sx + y*shx + tx); + *py = m * (x*shy + y*sy + ty); + } + + //------------------------------------------------------------------------ + inline void trans_perspective::transform_affine(double* x, double* y) const + { + double tmp = *x; + *x = tmp * sx + *y * shx + tx; + *y = tmp * shy + *y * sy + ty; + } + + //------------------------------------------------------------------------ + inline void trans_perspective::transform_2x2(double* x, double* y) const + { + double tmp = *x; + *x = tmp * sx + *y * shx; + *y = tmp * shy + *y * sy; + } + + //------------------------------------------------------------------------ + inline void trans_perspective::inverse_transform(double* x, double* y) const + { + trans_perspective t(*this); + if(t.invert()) t.transform(x, y); + } + + //------------------------------------------------------------------------ + inline void trans_perspective::store_to(double* m) const + { + *m++ = sx; *m++ = shy; *m++ = w0; + *m++ = shx; *m++ = sy; *m++ = w1; + *m++ = tx; *m++ = ty; *m++ = w2; + } + + //------------------------------------------------------------------------ + inline const trans_perspective& trans_perspective::load_from(const double* m) + { + sx = *m++; shy = *m++; w0 = *m++; + shx = *m++; sy = *m++; w1 = *m++; + tx = *m++; ty = *m++; w2 = *m++; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_perspective& + trans_perspective::from_affine(const trans_affine& a) + { + sx = a.sx; shy = a.shy; w0 = 0; + shx = a.shx; sy = a.sy; w1 = 0; + tx = a.tx; ty = a.ty; w2 = 1; + return *this; + } + + //------------------------------------------------------------------------ + inline double trans_perspective::determinant() const + { + return sx * (sy * w2 - ty * w1) + + shx * (ty * w0 - shy * w2) + + tx * (shy * w1 - sy * w0); + } + + //------------------------------------------------------------------------ + inline double trans_perspective::determinant_reciprocal() const + { + return 1.0 / determinant(); + } + + //------------------------------------------------------------------------ + inline bool trans_perspective::is_valid(double epsilon) const + { + return std::fabs(sx) > epsilon && std::fabs(sy) > epsilon && std::fabs(w2) > epsilon; + } + + //------------------------------------------------------------------------ + inline bool trans_perspective::is_identity(double epsilon) const + { + return is_equal_eps(sx, 1.0, epsilon) && + is_equal_eps(shy, 0.0, epsilon) && + is_equal_eps(w0, 0.0, epsilon) && + is_equal_eps(shx, 0.0, epsilon) && + is_equal_eps(sy, 1.0, epsilon) && + is_equal_eps(w1, 0.0, epsilon) && + is_equal_eps(tx, 0.0, epsilon) && + is_equal_eps(ty, 0.0, epsilon) && + is_equal_eps(w2, 1.0, epsilon); + } + + //------------------------------------------------------------------------ + inline bool trans_perspective::is_equal(const trans_perspective& m, + double epsilon) const + { + return is_equal_eps(sx, m.sx, epsilon) && + is_equal_eps(shy, m.shy, epsilon) && + is_equal_eps(w0, m.w0, epsilon) && + is_equal_eps(shx, m.shx, epsilon) && + is_equal_eps(sy, m.sy, epsilon) && + is_equal_eps(w1, m.w1, epsilon) && + is_equal_eps(tx, m.tx, epsilon) && + is_equal_eps(ty, m.ty, epsilon) && + is_equal_eps(w2, m.w2, epsilon); + } + + //------------------------------------------------------------------------ + inline double trans_perspective::scale() const + { + double x = 0.707106781 * sx + 0.707106781 * shx; + double y = 0.707106781 * shy + 0.707106781 * sy; + return std::sqrt(x*x + y*y); + } + + //------------------------------------------------------------------------ + inline double trans_perspective::rotation() const + { + double x1 = 0.0; + double y1 = 0.0; + double x2 = 1.0; + double y2 = 0.0; + transform(&x1, &y1); + transform(&x2, &y2); + return std::atan2(y2-y1, x2-x1); + } + + //------------------------------------------------------------------------ + void trans_perspective::translation(double* dx, double* dy) const + { + *dx = tx; + *dy = ty; + } + + //------------------------------------------------------------------------ + void trans_perspective::scaling(double* x, double* y) const + { + double x1 = 0.0; + double y1 = 0.0; + double x2 = 1.0; + double y2 = 1.0; + trans_perspective t(*this); + t *= trans_affine_rotation(-rotation()); + t.transform(&x1, &y1); + t.transform(&x2, &y2); + *x = x2 - x1; + *y = y2 - y1; + } + + //------------------------------------------------------------------------ + void trans_perspective::scaling_abs(double* x, double* y) const + { + *x = std::sqrt(sx * sx + shx * shx); + *y = std::sqrt(shy * shy + sy * sy); + } + + +} + +#endif + diff --git a/include/agg_trans_single_path.h b/include/agg_trans_single_path.h new file mode 100644 index 0000000..9f4bf53 --- /dev/null +++ b/include/agg_trans_single_path.h @@ -0,0 +1,97 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_TRANS_SINGLE_PATH_INCLUDED +#define AGG_TRANS_SINGLE_PATH_INCLUDED + +#include "agg_basics.h" +#include "agg_vertex_sequence.h" + +namespace agg +{ + + // See also: agg_trans_single_path.cpp + // + //-------------------------------------------------------trans_single_path + class trans_single_path + { + enum status_e + { + initial, + making_path, + ready + }; + + public: + typedef vertex_sequence<vertex_dist, 6> vertex_storage; + + trans_single_path(); + + //-------------------------------------------------------------------- + void base_length(double v) { m_base_length = v; } + double base_length() const { return m_base_length; } + + //-------------------------------------------------------------------- + void preserve_x_scale(bool f) { m_preserve_x_scale = f; } + bool preserve_x_scale() const { return m_preserve_x_scale; } + + //-------------------------------------------------------------------- + void reset(); + void move_to(double x, double y); + void line_to(double x, double y); + void finalize_path(); + + //-------------------------------------------------------------------- + template<class VertexSource> + void add_path(VertexSource& vs, unsigned path_id=0) + { + double x; + double y; + + unsigned cmd; + vs.rewind(path_id); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + if(is_move_to(cmd)) + { + move_to(x, y); + } + else + { + if(is_vertex(cmd)) + { + line_to(x, y); + } + } + } + finalize_path(); + } + + //-------------------------------------------------------------------- + double total_length() const; + void transform(double *x, double *y) const; + + private: + vertex_storage m_src_vertices; + double m_base_length; + double m_kindex; + status_e m_status; + bool m_preserve_x_scale; + }; + + +} + +#endif diff --git a/include/agg_trans_viewport.h b/include/agg_trans_viewport.h new file mode 100644 index 0000000..551cdf1 --- /dev/null +++ b/include/agg_trans_viewport.h @@ -0,0 +1,304 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Viewport transformer - simple orthogonal conversions from world coordinates +// to screen (device) ones. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_TRANS_VIEWPORT_INCLUDED +#define AGG_TRANS_VIEWPORT_INCLUDED + +#include <cstring> +#include <cmath> +#include "agg_trans_affine.h" + + +namespace agg +{ + + enum aspect_ratio_e + { + aspect_ratio_stretch, + aspect_ratio_meet, + aspect_ratio_slice + }; + + + //----------------------------------------------------------trans_viewport + class trans_viewport + { + public: + //------------------------------------------------------------------- + trans_viewport() : + m_world_x1(0.0), + m_world_y1(0.0), + m_world_x2(1.0), + m_world_y2(1.0), + m_device_x1(0.0), + m_device_y1(0.0), + m_device_x2(1.0), + m_device_y2(1.0), + m_aspect(aspect_ratio_stretch), + m_is_valid(true), + m_align_x(0.5), + m_align_y(0.5), + m_wx1(0.0), + m_wy1(0.0), + m_wx2(1.0), + m_wy2(1.0), + m_dx1(0.0), + m_dy1(0.0), + m_kx(1.0), + m_ky(1.0) + {} + + //------------------------------------------------------------------- + void preserve_aspect_ratio(double alignx, + double aligny, + aspect_ratio_e aspect) + { + m_align_x = alignx; + m_align_y = aligny; + m_aspect = aspect; + update(); + } + + //------------------------------------------------------------------- + void device_viewport(double x1, double y1, double x2, double y2) + { + m_device_x1 = x1; + m_device_y1 = y1; + m_device_x2 = x2; + m_device_y2 = y2; + update(); + } + + //------------------------------------------------------------------- + void world_viewport(double x1, double y1, double x2, double y2) + { + m_world_x1 = x1; + m_world_y1 = y1; + m_world_x2 = x2; + m_world_y2 = y2; + update(); + } + + //------------------------------------------------------------------- + void device_viewport(double* x1, double* y1, double* x2, double* y2) const + { + *x1 = m_device_x1; + *y1 = m_device_y1; + *x2 = m_device_x2; + *y2 = m_device_y2; + } + + //------------------------------------------------------------------- + void world_viewport(double* x1, double* y1, double* x2, double* y2) const + { + *x1 = m_world_x1; + *y1 = m_world_y1; + *x2 = m_world_x2; + *y2 = m_world_y2; + } + + //------------------------------------------------------------------- + void world_viewport_actual(double* x1, double* y1, + double* x2, double* y2) const + { + *x1 = m_wx1; + *y1 = m_wy1; + *x2 = m_wx2; + *y2 = m_wy2; + } + + //------------------------------------------------------------------- + bool is_valid() const { return m_is_valid; } + double align_x() const { return m_align_x; } + double align_y() const { return m_align_y; } + aspect_ratio_e aspect_ratio() const { return m_aspect; } + + //------------------------------------------------------------------- + void transform(double* x, double* y) const + { + *x = (*x - m_wx1) * m_kx + m_dx1; + *y = (*y - m_wy1) * m_ky + m_dy1; + } + + //------------------------------------------------------------------- + void transform_scale_only(double* x, double* y) const + { + *x *= m_kx; + *y *= m_ky; + } + + //------------------------------------------------------------------- + void inverse_transform(double* x, double* y) const + { + *x = (*x - m_dx1) / m_kx + m_wx1; + *y = (*y - m_dy1) / m_ky + m_wy1; + } + + //------------------------------------------------------------------- + void inverse_transform_scale_only(double* x, double* y) const + { + *x /= m_kx; + *y /= m_ky; + } + + //------------------------------------------------------------------- + double device_dx() const { return m_dx1 - m_wx1 * m_kx; } + double device_dy() const { return m_dy1 - m_wy1 * m_ky; } + + //------------------------------------------------------------------- + double scale_x() const + { + return m_kx; + } + + //------------------------------------------------------------------- + double scale_y() const + { + return m_ky; + } + + //------------------------------------------------------------------- + double scale() const + { + return (m_kx + m_ky) * 0.5; + } + + //------------------------------------------------------------------- + trans_affine to_affine() const + { + trans_affine mtx = trans_affine_translation(-m_wx1, -m_wy1); + mtx *= trans_affine_scaling(m_kx, m_ky); + mtx *= trans_affine_translation(m_dx1, m_dy1); + return mtx; + } + + //------------------------------------------------------------------- + trans_affine to_affine_scale_only() const + { + return trans_affine_scaling(m_kx, m_ky); + } + + //------------------------------------------------------------------- + unsigned byte_size() const + { + return sizeof(*this); + } + + void serialize(int8u* ptr) const + { + std::memcpy(ptr, this, sizeof(*this)); + } + + void deserialize(const int8u* ptr) + { + std::memcpy(this, ptr, sizeof(*this)); + } + + private: + void update(); + + double m_world_x1; + double m_world_y1; + double m_world_x2; + double m_world_y2; + double m_device_x1; + double m_device_y1; + double m_device_x2; + double m_device_y2; + aspect_ratio_e m_aspect; + bool m_is_valid; + double m_align_x; + double m_align_y; + double m_wx1; + double m_wy1; + double m_wx2; + double m_wy2; + double m_dx1; + double m_dy1; + double m_kx; + double m_ky; + }; + + + + //----------------------------------------------------------------------- + inline void trans_viewport::update() + { + const double epsilon = 1e-30; + if(std::fabs(m_world_x1 - m_world_x2) < epsilon || + std::fabs(m_world_y1 - m_world_y2) < epsilon || + std::fabs(m_device_x1 - m_device_x2) < epsilon || + std::fabs(m_device_y1 - m_device_y2) < epsilon) + { + m_wx1 = m_world_x1; + m_wy1 = m_world_y1; + m_wx2 = m_world_x1 + 1.0; + m_wy2 = m_world_y2 + 1.0; + m_dx1 = m_device_x1; + m_dy1 = m_device_y1; + m_kx = 1.0; + m_ky = 1.0; + m_is_valid = false; + return; + } + + double world_x1 = m_world_x1; + double world_y1 = m_world_y1; + double world_x2 = m_world_x2; + double world_y2 = m_world_y2; + double device_x1 = m_device_x1; + double device_y1 = m_device_y1; + double device_x2 = m_device_x2; + double device_y2 = m_device_y2; + if(m_aspect != aspect_ratio_stretch) + { + double d; + m_kx = (device_x2 - device_x1) / (world_x2 - world_x1); + m_ky = (device_y2 - device_y1) / (world_y2 - world_y1); + + if((m_aspect == aspect_ratio_meet) == (m_kx < m_ky)) + { + d = (world_y2 - world_y1) * m_ky / m_kx; + world_y1 += (world_y2 - world_y1 - d) * m_align_y; + world_y2 = world_y1 + d; + } + else + { + d = (world_x2 - world_x1) * m_kx / m_ky; + world_x1 += (world_x2 - world_x1 - d) * m_align_x; + world_x2 = world_x1 + d; + } + } + m_wx1 = world_x1; + m_wy1 = world_y1; + m_wx2 = world_x2; + m_wy2 = world_y2; + m_dx1 = device_x1; + m_dy1 = device_y1; + m_kx = (device_x2 - device_x1) / (world_x2 - world_x1); + m_ky = (device_y2 - device_y1) / (world_y2 - world_y1); + m_is_valid = true; + } + + +} + + +#endif diff --git a/include/agg_trans_warp_magnifier.h b/include/agg_trans_warp_magnifier.h new file mode 100644 index 0000000..38a92db --- /dev/null +++ b/include/agg_trans_warp_magnifier.h @@ -0,0 +1,56 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_WARP_MAGNIFIER_INCLUDED +#define AGG_WARP_MAGNIFIER_INCLUDED + + +namespace agg +{ + + //----------------------------------------------------trans_warp_magnifier + // + // See Inmplementation agg_trans_warp_magnifier.cpp + // + class trans_warp_magnifier + { + public: + trans_warp_magnifier() : m_xc(0.0), m_yc(0.0), m_magn(1.0), m_radius(1.0) {} + + void center(double x, double y) { m_xc = x; m_yc = y; } + void magnification(double m) { m_magn = m; } + void radius(double r) { m_radius = r; } + + double xc() const { return m_xc; } + double yc() const { return m_yc; } + double magnification() const { return m_magn; } + double radius() const { return m_radius; } + + void transform(double* x, double* y) const; + void inverse_transform(double* x, double* y) const; + + private: + double m_xc; + double m_yc; + double m_magn; + double m_radius; + }; + + +} + + +#endif + diff --git a/include/agg_vcgen_bspline.h b/include/agg_vcgen_bspline.h new file mode 100644 index 0000000..a294454 --- /dev/null +++ b/include/agg_vcgen_bspline.h @@ -0,0 +1,74 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_VCGEN_BSPLINE_INCLUDED +#define AGG_VCGEN_BSPLINE_INCLUDED + +#include "agg_basics.h" +#include "agg_array.h" +#include "agg_bspline.h" + + +namespace agg +{ + + //==========================================================vcgen_bspline + class vcgen_bspline + { + enum status_e + { + initial, + ready, + polygon, + end_poly, + stop + }; + + public: + typedef pod_bvector<point_d, 6> vertex_storage; + + vcgen_bspline(); + + void interpolation_step(double v) { m_interpolation_step = v; } + double interpolation_step() const { return m_interpolation_step; } + + // Vertex Generator Interface + void remove_all(); + void add_vertex(double x, double y, unsigned cmd); + + // Vertex Source Interface + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + vcgen_bspline(const vcgen_bspline&); + const vcgen_bspline& operator = (const vcgen_bspline&); + + vertex_storage m_src_vertices; + bspline m_spline_x; + bspline m_spline_y; + double m_interpolation_step; + unsigned m_closed; + status_e m_status; + unsigned m_src_vertex; + double m_cur_abscissa; + double m_max_abscissa; + }; + +} + + +#endif + diff --git a/include/agg_vcgen_contour.h b/include/agg_vcgen_contour.h new file mode 100644 index 0000000..8c25da1 --- /dev/null +++ b/include/agg_vcgen_contour.h @@ -0,0 +1,94 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_VCGEN_CONTOUR_INCLUDED +#define AGG_VCGEN_CONTOUR_INCLUDED + +#include "agg_math_stroke.h" + +namespace agg +{ + + //----------------------------------------------------------vcgen_contour + // + // See Implementation agg_vcgen_contour.cpp + // + class vcgen_contour + { + enum status_e + { + initial, + ready, + outline, + out_vertices, + end_poly, + stop + }; + + public: + typedef vertex_sequence<vertex_dist, 6> vertex_storage; + typedef pod_bvector<point_d, 6> coord_storage; + + vcgen_contour(); + + void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); } + void line_join(line_join_e lj) { m_stroker.line_join(lj); } + void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); } + + line_cap_e line_cap() const { return m_stroker.line_cap(); } + line_join_e line_join() const { return m_stroker.line_join(); } + inner_join_e inner_join() const { return m_stroker.inner_join(); } + + void width(double w) { m_stroker.width(m_width = w); } + void miter_limit(double ml) { m_stroker.miter_limit(ml); } + void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); } + void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); } + void approximation_scale(double as) { m_stroker.approximation_scale(as); } + + double width() const { return m_width; } + double miter_limit() const { return m_stroker.miter_limit(); } + double inner_miter_limit() const { return m_stroker.inner_miter_limit(); } + double approximation_scale() const { return m_stroker.approximation_scale(); } + + void auto_detect_orientation(bool v) { m_auto_detect = v; } + bool auto_detect_orientation() const { return m_auto_detect; } + + // Generator interface + void remove_all(); + void add_vertex(double x, double y, unsigned cmd); + + // Vertex Source Interface + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + vcgen_contour(const vcgen_contour&); + const vcgen_contour& operator = (const vcgen_contour&); + + math_stroke<coord_storage> m_stroker; + double m_width; + vertex_storage m_src_vertices; + coord_storage m_out_vertices; + status_e m_status; + unsigned m_src_vertex; + unsigned m_out_vertex; + unsigned m_closed; + unsigned m_orientation; + bool m_auto_detect; + }; + +} + +#endif diff --git a/include/agg_vcgen_dash.h b/include/agg_vcgen_dash.h new file mode 100644 index 0000000..c87dce4 --- /dev/null +++ b/include/agg_vcgen_dash.h @@ -0,0 +1,93 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Line dash generator +// +//---------------------------------------------------------------------------- +#ifndef AGG_VCGEN_DASH_INCLUDED +#define AGG_VCGEN_DASH_INCLUDED + +#include "agg_basics.h" +#include "agg_vertex_sequence.h" + +namespace agg +{ + + //---------------------------------------------------------------vcgen_dash + // + // See Implementation agg_vcgen_dash.cpp + // + class vcgen_dash + { + enum max_dashes_e + { + max_dashes = 32 + }; + + enum status_e + { + initial, + ready, + polyline, + stop + }; + + public: + typedef vertex_sequence<vertex_dist, 6> vertex_storage; + + vcgen_dash(); + + void remove_all_dashes(); + void add_dash(double dash_len, double gap_len); + void dash_start(double ds); + + void shorten(double s) { m_shorten = s; } + double shorten() const { return m_shorten; } + + // Vertex Generator Interface + void remove_all(); + void add_vertex(double x, double y, unsigned cmd); + + // Vertex Source Interface + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + vcgen_dash(const vcgen_dash&); + const vcgen_dash& operator = (const vcgen_dash&); + + void calc_dash_start(double ds); + + double m_dashes[max_dashes]; + double m_total_dash_len; + unsigned m_num_dashes; + double m_dash_start; + double m_shorten; + double m_curr_dash_start; + unsigned m_curr_dash; + double m_curr_rest; + const vertex_dist* m_v1; + const vertex_dist* m_v2; + + vertex_storage m_src_vertices; + unsigned m_closed; + status_e m_status; + unsigned m_src_vertex; + }; + + +} + +#endif diff --git a/include/agg_vcgen_markers_term.h b/include/agg_vcgen_markers_term.h new file mode 100644 index 0000000..ee1e74e --- /dev/null +++ b/include/agg_vcgen_markers_term.h @@ -0,0 +1,66 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_VCGEN_MARKERS_TERM_INCLUDED +#define AGG_VCGEN_MARKERS_TERM_INCLUDED + +#include "agg_basics.h" +#include "agg_vertex_sequence.h" + +namespace agg +{ + + //======================================================vcgen_markers_term + // + // See Implemantation agg_vcgen_markers_term.cpp + // Terminal markers generator (arrowhead/arrowtail) + // + //------------------------------------------------------------------------ + class vcgen_markers_term + { + public: + vcgen_markers_term() : m_curr_id(0), m_curr_idx(0) {} + + // Vertex Generator Interface + void remove_all(); + void add_vertex(double x, double y, unsigned cmd); + + // Vertex Source Interface + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + vcgen_markers_term(const vcgen_markers_term&); + const vcgen_markers_term& operator = (const vcgen_markers_term&); + + struct coord_type + { + double x, y; + + coord_type() {} + coord_type(double x_, double y_) : x(x_), y(y_) {} + }; + + typedef pod_bvector<coord_type, 6> coord_storage; + + coord_storage m_markers; + unsigned m_curr_id; + unsigned m_curr_idx; + }; + + +} + +#endif diff --git a/include/agg_vcgen_smooth_poly1.h b/include/agg_vcgen_smooth_poly1.h new file mode 100644 index 0000000..80fc0fb --- /dev/null +++ b/include/agg_vcgen_smooth_poly1.h @@ -0,0 +1,87 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_VCGEN_SMOOTH_POLY1_INCLUDED +#define AGG_VCGEN_SMOOTH_POLY1_INCLUDED + +#include "agg_basics.h" +#include "agg_vertex_sequence.h" + + +namespace agg +{ + + //======================================================vcgen_smooth_poly1 + // + // See Implementation agg_vcgen_smooth_poly1.cpp + // Smooth polygon generator + // + //------------------------------------------------------------------------ + class vcgen_smooth_poly1 + { + enum status_e + { + initial, + ready, + polygon, + ctrl_b, + ctrl_e, + ctrl1, + ctrl2, + end_poly, + stop + }; + + public: + typedef vertex_sequence<vertex_dist, 6> vertex_storage; + + vcgen_smooth_poly1(); + + void smooth_value(double v) { m_smooth_value = v * 0.5; } + double smooth_value() const { return m_smooth_value * 2.0; } + + // Vertex Generator Interface + void remove_all(); + void add_vertex(double x, double y, unsigned cmd); + + // Vertex Source Interface + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + vcgen_smooth_poly1(const vcgen_smooth_poly1&); + const vcgen_smooth_poly1& operator = (const vcgen_smooth_poly1&); + + void calculate(const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + const vertex_dist& v3); + + vertex_storage m_src_vertices; + double m_smooth_value; + unsigned m_closed; + status_e m_status; + unsigned m_src_vertex; + double m_ctrl1_x; + double m_ctrl1_y; + double m_ctrl2_x; + double m_ctrl2_y; + }; + +} + + +#endif + diff --git a/include/agg_vcgen_stroke.h b/include/agg_vcgen_stroke.h new file mode 100644 index 0000000..778223f --- /dev/null +++ b/include/agg_vcgen_stroke.h @@ -0,0 +1,102 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_VCGEN_STROKE_INCLUDED +#define AGG_VCGEN_STROKE_INCLUDED + +#include "agg_math_stroke.h" + + +namespace agg +{ + + //============================================================vcgen_stroke + // + // See Implementation agg_vcgen_stroke.cpp + // Stroke generator + // + //------------------------------------------------------------------------ + class vcgen_stroke + { + enum status_e + { + initial, + ready, + cap1, + cap2, + outline1, + close_first, + outline2, + out_vertices, + end_poly1, + end_poly2, + stop + }; + + public: + typedef vertex_sequence<vertex_dist, 6> vertex_storage; + typedef pod_bvector<point_d, 6> coord_storage; + + vcgen_stroke(); + + void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); } + void line_join(line_join_e lj) { m_stroker.line_join(lj); } + void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); } + + line_cap_e line_cap() const { return m_stroker.line_cap(); } + line_join_e line_join() const { return m_stroker.line_join(); } + inner_join_e inner_join() const { return m_stroker.inner_join(); } + + void width(double w) { m_stroker.width(w); } + void miter_limit(double ml) { m_stroker.miter_limit(ml); } + void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); } + void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); } + void approximation_scale(double as) { m_stroker.approximation_scale(as); } + + double width() const { return m_stroker.width(); } + double miter_limit() const { return m_stroker.miter_limit(); } + double inner_miter_limit() const { return m_stroker.inner_miter_limit(); } + double approximation_scale() const { return m_stroker.approximation_scale(); } + + void shorten(double s) { m_shorten = s; } + double shorten() const { return m_shorten; } + + // Vertex Generator Interface + void remove_all(); + void add_vertex(double x, double y, unsigned cmd); + + // Vertex Source Interface + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + vcgen_stroke(const vcgen_stroke&); + const vcgen_stroke& operator = (const vcgen_stroke&); + + math_stroke<coord_storage> m_stroker; + vertex_storage m_src_vertices; + coord_storage m_out_vertices; + double m_shorten; + unsigned m_closed; + status_e m_status; + status_e m_prev_status; + unsigned m_src_vertex; + unsigned m_out_vertex; + }; + + +} + +#endif diff --git a/include/agg_vcgen_vertex_sequence.h b/include/agg_vcgen_vertex_sequence.h new file mode 100644 index 0000000..5adc671 --- /dev/null +++ b/include/agg_vcgen_vertex_sequence.h @@ -0,0 +1,135 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_VCGEN_VERTEX_SEQUENCE_INCLUDED +#define AGG_VCGEN_VERTEX_SEQUENCE_INCLUDED + +#include "agg_basics.h" +#include "agg_vertex_sequence.h" +#include "agg_shorten_path.h" + +namespace agg +{ + + //===================================================vcgen_vertex_sequence + class vcgen_vertex_sequence + { + public: + typedef vertex_dist_cmd vertex_type; + typedef vertex_sequence<vertex_type, 6> vertex_storage; + + vcgen_vertex_sequence() : + m_flags(0), + m_cur_vertex(0), + m_shorten(0.0), + m_ready(false) + { + } + + // Vertex Generator Interface + void remove_all(); + void add_vertex(double x, double y, unsigned cmd); + + // Vertex Source Interface + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + void shorten(double s) { m_shorten = s; } + double shorten() const { return m_shorten; } + + private: + vcgen_vertex_sequence(const vcgen_vertex_sequence&); + const vcgen_vertex_sequence& operator = (const vcgen_vertex_sequence&); + + vertex_storage m_src_vertices; + unsigned m_flags; + unsigned m_cur_vertex; + double m_shorten; + bool m_ready; + }; + + + //------------------------------------------------------------------------ + inline void vcgen_vertex_sequence::remove_all() + { + m_ready = false; + m_src_vertices.remove_all(); + m_cur_vertex = 0; + m_flags = 0; + } + + //------------------------------------------------------------------------ + inline void vcgen_vertex_sequence::add_vertex(double x, double y, unsigned cmd) + { + m_ready = false; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(vertex_dist_cmd(x, y, cmd)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(vertex_dist_cmd(x, y, cmd)); + } + else + { + m_flags = cmd & path_flags_mask; + } + } + } + + + //------------------------------------------------------------------------ + inline void vcgen_vertex_sequence::rewind(unsigned) + { + if(!m_ready) + { + m_src_vertices.close(is_closed(m_flags)); + shorten_path(m_src_vertices, m_shorten, get_close_flag(m_flags)); + } + m_ready = true; + m_cur_vertex = 0; + } + + //------------------------------------------------------------------------ + inline unsigned vcgen_vertex_sequence::vertex(double* x, double* y) + { + if(!m_ready) + { + rewind(0); + } + + if(m_cur_vertex == m_src_vertices.size()) + { + ++m_cur_vertex; + return path_cmd_end_poly | m_flags; + } + + if(m_cur_vertex > m_src_vertices.size()) + { + return path_cmd_stop; + } + + vertex_type& v = m_src_vertices[m_cur_vertex++]; + *x = v.x; + *y = v.y; + return v.cmd; + } + + +} + +#endif diff --git a/include/agg_vertex_sequence.h b/include/agg_vertex_sequence.h new file mode 100644 index 0000000..2ad0701 --- /dev/null +++ b/include/agg_vertex_sequence.h @@ -0,0 +1,172 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// vertex_sequence container and vertex_dist struct +// +//---------------------------------------------------------------------------- +#ifndef AGG_VERTEX_SEQUENCE_INCLUDED +#define AGG_VERTEX_SEQUENCE_INCLUDED + +#include "agg_basics.h" +#include "agg_array.h" +#include "agg_math.h" + +namespace agg +{ + + //----------------------------------------------------------vertex_sequence + // Modified agg::pod_bvector. The data is interpreted as a sequence + // of vertices. It means that the type T must expose: + // + // bool T::operator() (const T& val) + // + // that is called every time new vertex is being added. The main purpose + // of this operator is the possibility to calculate some values during + // adding and to return true if the vertex fits some criteria or false if + // it doesn't. In the last case the new vertex is not added. + // + // The simple example is filtering coinciding vertices with calculation + // of the distance between the current and previous ones: + // + // struct vertex_dist + // { + // double x; + // double y; + // double dist; + // + // vertex_dist() {} + // vertex_dist(double x_, double y_) : + // x(x_), + // y(y_), + // dist(0.0) + // { + // } + // + // bool operator () (const vertex_dist& val) + // { + // return (dist = calc_distance(x, y, val.x, val.y)) > EPSILON; + // } + // }; + // + // Function close() calls this operator and removes the last vertex if + // necessary. + //------------------------------------------------------------------------ + template<class T, unsigned S=6> + class vertex_sequence : public pod_bvector<T, S> + { + public: + typedef pod_bvector<T, S> base_type; + + void add(const T& val); + void modify_last(const T& val); + void close(bool remove_flag); + }; + + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void vertex_sequence<T, S>::add(const T& val) + { + if(base_type::size() > 1) + { + if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) + { + base_type::remove_last(); + } + } + base_type::add(val); + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void vertex_sequence<T, S>::modify_last(const T& val) + { + base_type::remove_last(); + add(val); + } + + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void vertex_sequence<T, S>::close(bool closed) + { + while(base_type::size() > 1) + { + if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) break; + T t = (*this)[base_type::size() - 1]; + base_type::remove_last(); + modify_last(t); + } + + if(closed) + { + while(base_type::size() > 1) + { + if((*this)[base_type::size() - 1]((*this)[0])) break; + base_type::remove_last(); + } + } + } + + + //-------------------------------------------------------------vertex_dist + // Vertex (x, y) with the distance to the next one. The last vertex has + // distance between the last and the first points if the polygon is closed + // and 0.0 if it's a polyline. + struct vertex_dist + { + double x; + double y; + double dist; + + vertex_dist() {} + vertex_dist(double x_, double y_) : + x(x_), + y(y_), + dist(0.0) + { + } + + bool operator () (const vertex_dist& val) + { + bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon; + if(!ret) dist = 1.0 / vertex_dist_epsilon; + return ret; + } + }; + + + + //--------------------------------------------------------vertex_dist_cmd + // Save as the above but with additional "command" value + struct vertex_dist_cmd : public vertex_dist + { + unsigned cmd; + + vertex_dist_cmd() {} + vertex_dist_cmd(double x_, double y_, unsigned cmd_) : + vertex_dist(x_, y_), + cmd(cmd_) + { + } + }; + + +} + +#endif diff --git a/include/agg_vpgen_clip_polygon.h b/include/agg_vpgen_clip_polygon.h new file mode 100644 index 0000000..ded754e --- /dev/null +++ b/include/agg_vpgen_clip_polygon.h @@ -0,0 +1,83 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_VPGEN_CLIP_POLYGON_INCLUDED +#define AGG_VPGEN_CLIP_POLYGON_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //======================================================vpgen_clip_polygon + // + // See Implementation agg_vpgen_clip_polygon.cpp + // + class vpgen_clip_polygon + { + public: + vpgen_clip_polygon() : + m_clip_box(0, 0, 1, 1), + m_x1(0), + m_y1(0), + m_clip_flags(0), + m_num_vertices(0), + m_vertex(0), + m_cmd(path_cmd_move_to) + { + } + + void clip_box(double x1, double y1, double x2, double y2) + { + m_clip_box.x1 = x1; + m_clip_box.y1 = y1; + m_clip_box.x2 = x2; + m_clip_box.y2 = y2; + m_clip_box.normalize(); + } + + + double x1() const { return m_clip_box.x1; } + double y1() const { return m_clip_box.y1; } + double x2() const { return m_clip_box.x2; } + double y2() const { return m_clip_box.y2; } + + static bool auto_close() { return true; } + static bool auto_unclose() { return false; } + + void reset(); + void move_to(double x, double y); + void line_to(double x, double y); + unsigned vertex(double* x, double* y); + + private: + unsigned clipping_flags(double x, double y); + + private: + rect_d m_clip_box; + double m_x1; + double m_y1; + unsigned m_clip_flags; + double m_x[4]; + double m_y[4]; + unsigned m_num_vertices; + unsigned m_vertex; + unsigned m_cmd; + }; + +} + + +#endif diff --git a/include/agg_vpgen_clip_polyline.h b/include/agg_vpgen_clip_polyline.h new file mode 100644 index 0000000..b070a77 --- /dev/null +++ b/include/agg_vpgen_clip_polyline.h @@ -0,0 +1,78 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_VPGEN_CLIP_POLYLINE_INCLUDED +#define AGG_VPGEN_CLIP_POLYLINE_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //======================================================vpgen_clip_polyline + // + // See Implementation agg_vpgen_clip_polyline.cpp + // + class vpgen_clip_polyline + { + public: + vpgen_clip_polyline() : + m_clip_box(0, 0, 1, 1), + m_x1(0), + m_y1(0), + m_num_vertices(0), + m_vertex(0), + m_move_to(false) + { + } + + void clip_box(double x1, double y1, double x2, double y2) + { + m_clip_box.x1 = x1; + m_clip_box.y1 = y1; + m_clip_box.x2 = x2; + m_clip_box.y2 = y2; + m_clip_box.normalize(); + } + + double x1() const { return m_clip_box.x1; } + double y1() const { return m_clip_box.y1; } + double x2() const { return m_clip_box.x2; } + double y2() const { return m_clip_box.y2; } + + static bool auto_close() { return false; } + static bool auto_unclose() { return true; } + + void reset(); + void move_to(double x, double y); + void line_to(double x, double y); + unsigned vertex(double* x, double* y); + + private: + rect_d m_clip_box; + double m_x1; + double m_y1; + double m_x[2]; + double m_y[2]; + unsigned m_cmd[2]; + unsigned m_num_vertices; + unsigned m_vertex; + bool m_move_to; + }; + +} + + +#endif diff --git a/include/agg_vpgen_segmentator.h b/include/agg_vpgen_segmentator.h new file mode 100644 index 0000000..77248ee --- /dev/null +++ b/include/agg_vpgen_segmentator.h @@ -0,0 +1,60 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#ifndef AGG_VPGEN_SEGMENTATOR_INCLUDED +#define AGG_VPGEN_SEGMENTATOR_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //=======================================================vpgen_segmentator + // + // See Implementation agg_vpgen_segmentator.cpp + // + class vpgen_segmentator + { + public: + vpgen_segmentator() : m_approximation_scale(1.0) {} + + void approximation_scale(double s) { m_approximation_scale = s; } + double approximation_scale() const { return m_approximation_scale; } + + static bool auto_close() { return false; } + static bool auto_unclose() { return false; } + + void reset() { m_cmd = path_cmd_stop; } + void move_to(double x, double y); + void line_to(double x, double y); + unsigned vertex(double* x, double* y); + + private: + double m_approximation_scale; + double m_x1; + double m_y1; + double m_dx; + double m_dy; + double m_dl; + double m_ddl; + unsigned m_cmd; + }; + + + +} + +#endif + diff --git a/include/ctrl/Makefile.am b/include/ctrl/Makefile.am new file mode 100644 index 0000000..660c583 --- /dev/null +++ b/include/ctrl/Makefile.am @@ -0,0 +1,4 @@ +aggincludedir = $(includedir)/agg2/ctrl +agginclude_HEADERS = agg_ctrl.h agg_gamma_spline.h agg_scale_ctrl.h agg_spline_ctrl.h \ + agg_cbox_ctrl.h agg_gamma_ctrl.h agg_rbox_ctrl.h agg_slider_ctrl.h \ + agg_bezier_ctrl.h agg_polygon_ctrl.h diff --git a/include/ctrl/agg_bezier_ctrl.h b/include/ctrl/agg_bezier_ctrl.h new file mode 100644 index 0000000..f300d73 --- /dev/null +++ b/include/ctrl/agg_bezier_ctrl.h @@ -0,0 +1,196 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes bezier_ctrl_impl, bezier_ctrl +// +//---------------------------------------------------------------------------- + +#ifndef AGG_BEZIER_CTRL_INCLUDED +#define AGG_BEZIER_CTRL_INCLUDED + +#include "agg_math.h" +#include "agg_ellipse.h" +#include "agg_trans_affine.h" +#include "agg_color_rgba.h" +#include "agg_conv_stroke.h" +#include "agg_conv_curve.h" +#include "agg_polygon_ctrl.h" + + +namespace agg +{ + + //--------------------------------------------------------bezier_ctrl_impl + class bezier_ctrl_impl : public ctrl + { + public: + bezier_ctrl_impl(); + + void curve(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4); + curve4& curve(); + + double x1() const { return m_poly.xn(0); } + double y1() const { return m_poly.yn(0); } + double x2() const { return m_poly.xn(1); } + double y2() const { return m_poly.yn(1); } + double x3() const { return m_poly.xn(2); } + double y3() const { return m_poly.yn(2); } + double x4() const { return m_poly.xn(3); } + double y4() const { return m_poly.yn(3); } + + void x1(double x) { m_poly.xn(0) = x; } + void y1(double y) { m_poly.yn(0) = y; } + void x2(double x) { m_poly.xn(1) = x; } + void y2(double y) { m_poly.yn(1) = y; } + void x3(double x) { m_poly.xn(2) = x; } + void y3(double y) { m_poly.yn(2) = y; } + void x4(double x) { m_poly.xn(3) = x; } + void y4(double y) { m_poly.yn(3) = y; } + + void line_width(double w) { m_stroke.width(w); } + double line_width() const { return m_stroke.width(); } + + void point_radius(double r) { m_poly.point_radius(r); } + double point_radius() const { return m_poly.point_radius(); } + + virtual bool in_rect(double x, double y) const; + virtual bool on_mouse_button_down(double x, double y); + virtual bool on_mouse_button_up(double x, double y); + virtual bool on_mouse_move(double x, double y, bool button_flag); + virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); + + // Vertex source interface + unsigned num_paths() { return 7; }; + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + + private: + curve4 m_curve; + ellipse m_ellipse; + conv_stroke<curve4> m_stroke; + polygon_ctrl_impl m_poly; + unsigned m_idx; + }; + + + + //----------------------------------------------------------bezier_ctrl + template<class ColorT> class bezier_ctrl : public bezier_ctrl_impl + { + public: + bezier_ctrl() : + m_color(rgba(0.0, 0.0, 0.0)) + { + } + + void line_color(const ColorT& c) { m_color = c; } + const ColorT& color(unsigned) const { return m_color; } + + private: + bezier_ctrl(const bezier_ctrl<ColorT>&); + const bezier_ctrl<ColorT>& operator = (const bezier_ctrl<ColorT>&); + + ColorT m_color; + }; + + + + + + //--------------------------------------------------------curve3_ctrl_impl + class curve3_ctrl_impl : public ctrl + { + public: + curve3_ctrl_impl(); + + void curve(double x1, double y1, + double x2, double y2, + double x3, double y3); + curve3& curve(); + + double x1() const { return m_poly.xn(0); } + double y1() const { return m_poly.yn(0); } + double x2() const { return m_poly.xn(1); } + double y2() const { return m_poly.yn(1); } + double x3() const { return m_poly.xn(2); } + double y3() const { return m_poly.yn(2); } + + void x1(double x) { m_poly.xn(0) = x; } + void y1(double y) { m_poly.yn(0) = y; } + void x2(double x) { m_poly.xn(1) = x; } + void y2(double y) { m_poly.yn(1) = y; } + void x3(double x) { m_poly.xn(2) = x; } + void y3(double y) { m_poly.yn(2) = y; } + + void line_width(double w) { m_stroke.width(w); } + double line_width() const { return m_stroke.width(); } + + void point_radius(double r) { m_poly.point_radius(r); } + double point_radius() const { return m_poly.point_radius(); } + + virtual bool in_rect(double x, double y) const; + virtual bool on_mouse_button_down(double x, double y); + virtual bool on_mouse_button_up(double x, double y); + virtual bool on_mouse_move(double x, double y, bool button_flag); + virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); + + // Vertex source interface + unsigned num_paths() { return 6; }; + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + + private: + curve3 m_curve; + ellipse m_ellipse; + conv_stroke<curve3> m_stroke; + polygon_ctrl_impl m_poly; + unsigned m_idx; + }; + + + + //----------------------------------------------------------curve3_ctrl + template<class ColorT> class curve3_ctrl : public curve3_ctrl_impl + { + public: + curve3_ctrl() : + m_color(rgba(0.0, 0.0, 0.0)) + { + } + + void line_color(const ColorT& c) { m_color = c; } + const ColorT& color(unsigned i) const { return m_color; } + + private: + curve3_ctrl(const curve3_ctrl<ColorT>&); + const curve3_ctrl<ColorT>& operator = (const curve3_ctrl<ColorT>&); + + ColorT m_color; + }; + + + + +} + + + +#endif + diff --git a/include/ctrl/agg_cbox_ctrl.h b/include/ctrl/agg_cbox_ctrl.h new file mode 100644 index 0000000..7ecbce2 --- /dev/null +++ b/include/ctrl/agg_cbox_ctrl.h @@ -0,0 +1,112 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes cbox_ctrl_impl, cbox_ctrl +// +//---------------------------------------------------------------------------- + +#ifndef AGG_CBOX_CTRL_INCLUDED +#define AGG_CBOX_CTRL_INCLUDED + +#include "agg_basics.h" +#include "agg_conv_stroke.h" +#include "agg_gsv_text.h" +#include "agg_trans_affine.h" +#include "agg_color_rgba.h" +#include "agg_ctrl.h" + + + +namespace agg +{ + + //----------------------------------------------------------cbox_ctrl_impl + class cbox_ctrl_impl : public ctrl + { + public: + cbox_ctrl_impl(double x, double y, const char* label, bool flip_y=false); + + void text_thickness(double t) { m_text_thickness = t; } + void text_size(double h, double w=0.0); + + const char* label() { return m_label; } + void label(const char* l); + + bool status() const { return m_status; } + void status(bool st) { m_status = st; } + + virtual bool in_rect(double x, double y) const; + virtual bool on_mouse_button_down(double x, double y); + virtual bool on_mouse_button_up(double x, double y); + virtual bool on_mouse_move(double x, double y, bool button_flag); + virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); + + // Vertex soutce interface + unsigned num_paths() { return 3; }; + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + double m_text_thickness; + double m_text_height; + double m_text_width; + char m_label[128]; + bool m_status; + double m_vx[32]; + double m_vy[32]; + + gsv_text m_text; + conv_stroke<gsv_text> m_text_poly; + + unsigned m_idx; + unsigned m_vertex; + }; + + + //----------------------------------------------------------cbox_ctrl_impl + template<class ColorT> class cbox_ctrl : public cbox_ctrl_impl + { + public: + cbox_ctrl(double x, double y, const char* label, bool flip_y=false) : + cbox_ctrl_impl(x, y, label, flip_y), + m_text_color(rgba(0.0, 0.0, 0.0)), + m_inactive_color(rgba(0.0, 0.0, 0.0)), + m_active_color(rgba(0.4, 0.0, 0.0)) + { + m_colors[0] = &m_inactive_color; + m_colors[1] = &m_text_color; + m_colors[2] = &m_active_color; + } + + void text_color(const ColorT& c) { m_text_color = c; } + void inactive_color(const ColorT& c) { m_inactive_color = c; } + void active_color(const ColorT& c) { m_active_color = c; } + + const ColorT& color(unsigned i) const { return *m_colors[i]; } + + private: + cbox_ctrl(const cbox_ctrl<ColorT>&); + const cbox_ctrl<ColorT>& operator = (const cbox_ctrl<ColorT>&); + + ColorT m_text_color; + ColorT m_inactive_color; + ColorT m_active_color; + ColorT* m_colors[3]; + }; + + +} + +#endif diff --git a/include/ctrl/agg_ctrl.h b/include/ctrl/agg_ctrl.h new file mode 100644 index 0000000..7e811c6 --- /dev/null +++ b/include/ctrl/agg_ctrl.h @@ -0,0 +1,118 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Function render_ctrl +// +//---------------------------------------------------------------------------- + +#ifndef AGG_CTRL_INCLUDED +#define AGG_CTRL_INCLUDED + +#include "agg_trans_affine.h" +#include "agg_renderer_scanline.h" + +namespace agg +{ + + //--------------------------------------------------------------------ctrl + class ctrl + { + public: + //-------------------------------------------------------------------- + virtual ~ctrl() {} + ctrl(double x1, double y1, double x2, double y2, bool flip_y) : + m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2), + m_flip_y(flip_y), + m_mtx(0) + { + } + + //-------------------------------------------------------------------- + virtual bool in_rect(double x, double y) const = 0; + virtual bool on_mouse_button_down(double x, double y) = 0; + virtual bool on_mouse_button_up(double x, double y) = 0; + virtual bool on_mouse_move(double x, double y, bool button_flag) = 0; + virtual bool on_arrow_keys(bool left, bool right, bool down, bool up) = 0; + + //-------------------------------------------------------------------- + void transform(const trans_affine& mtx) { m_mtx = &mtx; } + void no_transform() { m_mtx = 0; } + + //-------------------------------------------------------------------- + void transform_xy(double* x, double* y) const + { + if(m_flip_y) *y = m_y1 + m_y2 - *y; + if(m_mtx) m_mtx->transform(x, y); + } + + //-------------------------------------------------------------------- + void inverse_transform_xy(double* x, double* y) const + { + if(m_mtx) m_mtx->inverse_transform(x, y); + if(m_flip_y) *y = m_y1 + m_y2 - *y; + } + + //-------------------------------------------------------------------- + double scale() const { return m_mtx ? m_mtx->scale() : 1.0; } + + private: + ctrl(const ctrl&); + const ctrl& operator = (const ctrl&); + + protected: + double m_x1; + double m_y1; + double m_x2; + double m_y2; + + private: + bool m_flip_y; + const trans_affine* m_mtx; + }; + + + //-------------------------------------------------------------------- + template<class Rasterizer, class Scanline, class Renderer, class Ctrl> + void render_ctrl(Rasterizer& ras, Scanline& sl, Renderer& r, Ctrl& c) + { + unsigned i; + for(i = 0; i < c.num_paths(); i++) + { + ras.reset(); + ras.add_path(c, i); + render_scanlines_aa_solid(ras, sl, r, c.color(i)); + } + } + + + //-------------------------------------------------------------------- + template<class Rasterizer, class Scanline, class Renderer, class Ctrl> + void render_ctrl_rs(Rasterizer& ras, Scanline& sl, Renderer& r, Ctrl& c) + { + unsigned i; + for(i = 0; i < c.num_paths(); i++) + { + ras.reset(); + ras.add_path(c, i); + r.color(c.color(i)); + render_scanlines(ras, sl, r); + } + } + + +} + + +#endif diff --git a/include/ctrl/agg_gamma_ctrl.h b/include/ctrl/agg_gamma_ctrl.h new file mode 100644 index 0000000..0a645a7 --- /dev/null +++ b/include/ctrl/agg_gamma_ctrl.h @@ -0,0 +1,170 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class gamma_ctrl +// +//---------------------------------------------------------------------------- + +#ifndef AGG_GAMMA_CTRL_INCLUDED +#define AGG_GAMMA_CTRL_INCLUDED + +#include "agg_basics.h" +#include "agg_gamma_spline.h" +#include "agg_ellipse.h" +#include "agg_conv_stroke.h" +#include "agg_gsv_text.h" +#include "agg_trans_affine.h" +#include "agg_color_rgba.h" +#include "agg_ctrl.h" + +namespace agg +{ + //------------------------------------------------------------------------ + // Class that can be used to create an interactive control to set up + // gamma arrays. + //------------------------------------------------------------------------ + class gamma_ctrl_impl : public ctrl + { + public: + gamma_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); + + // Set other parameters + void border_width(double t, double extra=0.0); + void curve_width(double t) { m_curve_width = t; } + void grid_width(double t) { m_grid_width = t; } + void text_thickness(double t) { m_text_thickness = t; } + void text_size(double h, double w=0.0); + void point_size(double s) { m_point_size = s; } + + // Event handlers. Just call them if the respective events + // in your system occure. The functions return true if redrawing + // is required. + virtual bool in_rect(double x, double y) const; + virtual bool on_mouse_button_down(double x, double y); + virtual bool on_mouse_button_up(double x, double y); + virtual bool on_mouse_move(double x, double y, bool button_flag); + virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); + + void change_active_point(); + + // A copy of agg::gamma_spline interface + void values(double kx1, double ky1, double kx2, double ky2); + void values(double* kx1, double* ky1, double* kx2, double* ky2) const; + const unsigned char* gamma() const { return m_gamma_spline.gamma(); } + double y(double x) const { return m_gamma_spline.y(x); } + double operator() (double x) const { return m_gamma_spline.y(x); } + const gamma_spline& get_gamma_spline() const { return m_gamma_spline; } + + // Vertex soutce interface + unsigned num_paths() { return 7; } + void rewind(unsigned idx); + unsigned vertex(double* x, double* y); + + private: + void calc_spline_box(); + void calc_points(); + void calc_values(); + + gamma_spline m_gamma_spline; + double m_border_width; + double m_border_extra; + double m_curve_width; + double m_grid_width; + double m_text_thickness; + double m_point_size; + double m_text_height; + double m_text_width; + double m_xc1; + double m_yc1; + double m_xc2; + double m_yc2; + double m_xs1; + double m_ys1; + double m_xs2; + double m_ys2; + double m_xt1; + double m_yt1; + double m_xt2; + double m_yt2; + conv_stroke<gamma_spline> m_curve_poly; + ellipse m_ellipse; + gsv_text m_text; + conv_stroke<gsv_text> m_text_poly; + unsigned m_idx; + unsigned m_vertex; + double m_vx[32]; + double m_vy[32]; + double m_xp1; + double m_yp1; + double m_xp2; + double m_yp2; + bool m_p1_active; + unsigned m_mouse_point; + double m_pdx; + double m_pdy; + }; + + + + template<class ColorT> class gamma_ctrl : public gamma_ctrl_impl + { + public: + gamma_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : + gamma_ctrl_impl(x1, y1, x2, y2, flip_y), + m_background_color(rgba(1.0, 1.0, 0.9)), + m_border_color(rgba(0.0, 0.0, 0.0)), + m_curve_color(rgba(0.0, 0.0, 0.0)), + m_grid_color(rgba(0.2, 0.2, 0.0)), + m_inactive_pnt_color(rgba(0.0, 0.0, 0.0)), + m_active_pnt_color(rgba(1.0, 0.0, 0.0)), + m_text_color(rgba(0.0, 0.0, 0.0)) + { + m_colors[0] = &m_background_color; + m_colors[1] = &m_border_color; + m_colors[2] = &m_curve_color; + m_colors[3] = &m_grid_color; + m_colors[4] = &m_inactive_pnt_color; + m_colors[5] = &m_active_pnt_color; + m_colors[6] = &m_text_color; + } + + // Set colors + void background_color(const ColorT& c) { m_background_color = c; } + void border_color(const ColorT& c) { m_border_color = c; } + void curve_color(const ColorT& c) { m_curve_color = c; } + void grid_color(const ColorT& c) { m_grid_color = c; } + void inactive_pnt_color(const ColorT& c) { m_inactive_pnt_color = c; } + void active_pnt_color(const ColorT& c) { m_active_pnt_color = c; } + void text_color(const ColorT& c) { m_text_color = c; } + const ColorT& color(unsigned i) const { return *m_colors[i]; } + + private: + gamma_ctrl(const gamma_ctrl<ColorT>&); + const gamma_ctrl<ColorT>& operator = (const gamma_ctrl<ColorT>&); + + ColorT m_background_color; + ColorT m_border_color; + ColorT m_curve_color; + ColorT m_grid_color; + ColorT m_inactive_pnt_color; + ColorT m_active_pnt_color; + ColorT m_text_color; + ColorT* m_colors[7]; + }; + + +} + +#endif diff --git a/include/ctrl/agg_gamma_spline.h b/include/ctrl/agg_gamma_spline.h new file mode 100644 index 0000000..4f21710 --- /dev/null +++ b/include/ctrl/agg_gamma_spline.h @@ -0,0 +1,95 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class gamma_spline +// +//---------------------------------------------------------------------------- + +#ifndef AGG_GAMMA_SPLINE_INCLUDED +#define AGG_GAMMA_SPLINE_INCLUDED + +#include "agg_basics.h" +#include "agg_bspline.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + // Class-helper for calculation gamma-correction arrays. A gamma-correction + // array is an array of 256 unsigned chars that determine the actual values + // of Anti-Aliasing for each pixel coverage value from 0 to 255. If all the + // values in the array are equal to its index, i.e. 0,1,2,3,... there's + // no gamma-correction. Class agg::polyfill allows you to use custom + // gamma-correction arrays. You can calculate it using any approach, and + // class gamma_spline allows you to calculate almost any reasonable shape + // of the gamma-curve with using only 4 values - kx1, ky1, kx2, ky2. + // + // kx2 + // +----------------------------------+ + // | | | . | + // | | | . | ky2 + // | | . ------| + // | | . | + // | | . | + // |----------------.|----------------| + // | . | | + // | . | | + // |-------. | | + // ky1 | . | | | + // | . | | | + // +----------------------------------+ + // kx1 + // + // Each value can be in range [0...2]. Value 1.0 means one quarter of the + // bounding rectangle. Function values() calculates the curve by these + // 4 values. After calling it one can get the gamma-array with call gamma(). + // Class also supports the vertex source interface, i.e rewind() and + // vertex(). It's made for convinience and used in class gamma_ctrl. + // Before calling rewind/vertex one must set the bounding box + // box() using pixel coordinates. + //------------------------------------------------------------------------ + + class gamma_spline + { + public: + gamma_spline(); + + void values(double kx1, double ky1, double kx2, double ky2); + const unsigned char* gamma() const { return m_gamma; } + double y(double x) const; + void values(double* kx1, double* ky1, double* kx2, double* ky2) const; + void box(double x1, double y1, double x2, double y2); + + void rewind(unsigned); + unsigned vertex(double* x, double* y); + + private: + unsigned char m_gamma[256]; + double m_x[4]; + double m_y[4]; + bspline m_spline; + double m_x1; + double m_y1; + double m_x2; + double m_y2; + double m_cur_x; + }; + + + + +} + +#endif diff --git a/include/ctrl/agg_polygon_ctrl.h b/include/ctrl/agg_polygon_ctrl.h new file mode 100644 index 0000000..9a1f389 --- /dev/null +++ b/include/ctrl/agg_polygon_ctrl.h @@ -0,0 +1,166 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes polygon_ctrl_impl, polygon_ctrl +// +//---------------------------------------------------------------------------- + +#ifndef POLYGON_CTRL_INCLUDED +#define POLYGON_CTRL_INCLUDED + +#include "agg_array.h" +#include "agg_conv_stroke.h" +#include "agg_ellipse.h" +#include "agg_color_rgba.h" +#include "agg_ctrl.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 polygon_ctrl_impl : public ctrl + { + public: + polygon_ctrl_impl(unsigned np, double point_radius=5); + + 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]; } + + void line_width(double w) { m_stroke.width(w); } + double line_width() const { return m_stroke.width(); } + + void point_radius(double r) { m_point_radius = r; } + double point_radius() const { return m_point_radius; } + + void in_polygon_check(bool f) { m_in_polygon_check = f; } + bool in_polygon_check() const { return m_in_polygon_check; } + + void close(bool f) { m_vs.close(f); } + bool close() const { return m_vs.close(); } + + // Vertex source interface + unsigned num_paths() { return 1; } + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + virtual bool in_rect(double x, double y) const; + virtual bool on_mouse_button_down(double x, double y); + virtual bool on_mouse_button_up(double x, double y); + virtual bool on_mouse_move(double x, double y, bool button_flag); + virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); + + + 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; + bool m_in_polygon_check; + }; + + + + //----------------------------------------------------------polygon_ctrl + template<class ColorT> class polygon_ctrl : public polygon_ctrl_impl + { + public: + polygon_ctrl(unsigned np, double point_radius=5) : + polygon_ctrl_impl(np, point_radius), + m_color(rgba(0.0, 0.0, 0.0)) + { + } + + void line_color(const ColorT& c) { m_color = c; } + const ColorT& color(unsigned) const { return m_color; } + + private: + polygon_ctrl(const polygon_ctrl<ColorT>&); + const polygon_ctrl<ColorT>& operator = (const polygon_ctrl<ColorT>&); + + ColorT m_color; + }; + + + + +} + +#endif + diff --git a/include/ctrl/agg_rbox_ctrl.h b/include/ctrl/agg_rbox_ctrl.h new file mode 100644 index 0000000..4d47bcc --- /dev/null +++ b/include/ctrl/agg_rbox_ctrl.h @@ -0,0 +1,141 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes rbox_ctrl_impl, rbox_ctrl +// +//---------------------------------------------------------------------------- + +#ifndef AGG_RBOX_CTRL_INCLUDED +#define AGG_RBOX_CTRL_INCLUDED + +#include "agg_array.h" +#include "agg_ellipse.h" +#include "agg_conv_stroke.h" +#include "agg_gsv_text.h" +#include "agg_trans_affine.h" +#include "agg_color_rgba.h" +#include "agg_ctrl.h" + + + +namespace agg +{ + + //------------------------------------------------------------------------ + class rbox_ctrl_impl : public ctrl + { + public: + rbox_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); + + void border_width(double t, double extra=0.0); + void text_thickness(double t) { m_text_thickness = t; } + void text_size(double h, double w=0.0); + + void add_item(const char* text); + int cur_item() const { return m_cur_item; } + void cur_item(int i) { m_cur_item = i; } + + virtual bool in_rect(double x, double y) const; + virtual bool on_mouse_button_down(double x, double y); + virtual bool on_mouse_button_up(double x, double y); + virtual bool on_mouse_move(double x, double y, bool button_flag); + virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); + + // Vertex soutce interface + unsigned num_paths() { return 5; }; + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + void calc_rbox(); + + double m_border_width; + double m_border_extra; + double m_text_thickness; + double m_text_height; + double m_text_width; + pod_array<char> m_items[32]; + unsigned m_num_items; + int m_cur_item; + + double m_xs1; + double m_ys1; + double m_xs2; + double m_ys2; + + double m_vx[32]; + double m_vy[32]; + unsigned m_draw_item; + double m_dy; + + ellipse m_ellipse; + conv_stroke<ellipse> m_ellipse_poly; + gsv_text m_text; + conv_stroke<gsv_text> m_text_poly; + + unsigned m_idx; + unsigned m_vertex; + }; + + + + //------------------------------------------------------------------------ + template<class ColorT> class rbox_ctrl : public rbox_ctrl_impl + { + public: + rbox_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : + rbox_ctrl_impl(x1, y1, x2, y2, flip_y), + m_background_color(rgba(1.0, 1.0, 0.9)), + m_border_color(rgba(0.0, 0.0, 0.0)), + m_text_color(rgba(0.0, 0.0, 0.0)), + m_inactive_color(rgba(0.0, 0.0, 0.0)), + m_active_color(rgba(0.4, 0.0, 0.0)) + { + m_colors[0] = &m_background_color; + m_colors[1] = &m_border_color; + m_colors[2] = &m_text_color; + m_colors[3] = &m_inactive_color; + m_colors[4] = &m_active_color; + } + + + void background_color(const ColorT& c) { m_background_color = c; } + void border_color(const ColorT& c) { m_border_color = c; } + void text_color(const ColorT& c) { m_text_color = c; } + void inactive_color(const ColorT& c) { m_inactive_color = c; } + void active_color(const ColorT& c) { m_active_color = c; } + + const ColorT& color(unsigned i) const { return *m_colors[i]; } + + private: + rbox_ctrl(const rbox_ctrl<ColorT>&); + const rbox_ctrl<ColorT>& operator = (const rbox_ctrl<ColorT>&); + + ColorT m_background_color; + ColorT m_border_color; + ColorT m_text_color; + ColorT m_inactive_color; + ColorT m_active_color; + ColorT* m_colors[5]; + }; + + + +} + + + +#endif + diff --git a/include/ctrl/agg_scale_ctrl.h b/include/ctrl/agg_scale_ctrl.h new file mode 100644 index 0000000..b1e32c2 --- /dev/null +++ b/include/ctrl/agg_scale_ctrl.h @@ -0,0 +1,146 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes scale_ctrl_impl, scale_ctrl +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SCALE_CTRL_INCLUDED +#define AGG_SCALE_CTRL_INCLUDED + +#include "agg_basics.h" +#include "agg_math.h" +#include "agg_ellipse.h" +#include "agg_trans_affine.h" +#include "agg_color_rgba.h" +#include "agg_ctrl.h" + + +namespace agg +{ + + //------------------------------------------------------------------------ + class scale_ctrl_impl : public ctrl + { + enum move_e + { + move_nothing, + move_value1, + move_value2, + move_slider + }; + + public: + scale_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); + + void border_thickness(double t, double extra=0.0); + void resize(double x1, double y1, double x2, double y2); + + double min_delta() const { return m_min_d; } + void min_delta(double d) { m_min_d = d; } + + double value1() const { return m_value1; } + void value1(double value); + + double value2() const { return m_value2; } + void value2(double value); + + void move(double d); + + virtual bool in_rect(double x, double y) const; + virtual bool on_mouse_button_down(double x, double y); + virtual bool on_mouse_button_up(double x, double y); + virtual bool on_mouse_move(double x, double y, bool button_flag); + virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); + + // Vertex soutce interface + unsigned num_paths() { return 5; }; + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + void calc_box(); + + double m_border_thickness; + double m_border_extra; + double m_value1; + double m_value2; + double m_min_d; + double m_xs1; + double m_ys1; + double m_xs2; + double m_ys2; + double m_pdx; + double m_pdy; + move_e m_move_what; + double m_vx[32]; + double m_vy[32]; + + ellipse m_ellipse; + + unsigned m_idx; + unsigned m_vertex; + + }; + + + + //------------------------------------------------------------------------ + template<class ColorT> class scale_ctrl : public scale_ctrl_impl + { + public: + scale_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : + scale_ctrl_impl(x1, y1, x2, y2, flip_y), + m_background_color(rgba(1.0, 0.9, 0.8)), + m_border_color(rgba(0.0, 0.0, 0.0)), + m_pointers_color(rgba(0.8, 0.0, 0.0, 0.8)), + m_slider_color(rgba(0.2, 0.1, 0.0, 0.6)) + { + m_colors[0] = &m_background_color; + m_colors[1] = &m_border_color; + m_colors[2] = &m_pointers_color; + m_colors[3] = &m_pointers_color; + m_colors[4] = &m_slider_color; + } + + + void background_color(const ColorT& c) { m_background_color = c; } + void border_color(const ColorT& c) { m_border_color = c; } + void pointers_color(const ColorT& c) { m_pointers_color = c; } + void slider_color(const ColorT& c) { m_slider_color = c; } + + const ColorT& color(unsigned i) const { return *m_colors[i]; } + + private: + scale_ctrl(const scale_ctrl<ColorT>&); + const scale_ctrl<ColorT>& operator = (const scale_ctrl<ColorT>&); + + ColorT m_background_color; + ColorT m_border_color; + ColorT m_pointers_color; + ColorT m_slider_color; + ColorT* m_colors[5]; + }; + + + + + +} + + + +#endif + diff --git a/include/ctrl/agg_slider_ctrl.h b/include/ctrl/agg_slider_ctrl.h new file mode 100644 index 0000000..b50a95c --- /dev/null +++ b/include/ctrl/agg_slider_ctrl.h @@ -0,0 +1,150 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes slider_ctrl_impl, slider_ctrl +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SLIDER_CTRL_INCLUDED +#define AGG_SLIDER_CTRL_INCLUDED + +#include "agg_basics.h" +#include "agg_math.h" +#include "agg_ellipse.h" +#include "agg_trans_affine.h" +#include "agg_color_rgba.h" +#include "agg_gsv_text.h" +#include "agg_conv_stroke.h" +#include "agg_path_storage.h" +#include "agg_ctrl.h" + + +namespace agg +{ + + //--------------------------------------------------------slider_ctrl_impl + class slider_ctrl_impl : public ctrl + { + public: + slider_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false); + + void border_width(double t, double extra=0.0); + + void range(double min, double max) { m_min = min; m_max = max; } + void num_steps(unsigned num) { m_num_steps = num; } + void label(const char* fmt); + void text_thickness(double t) { m_text_thickness = t; } + + bool descending() const { return m_descending; } + void descending(bool v) { m_descending = v; } + + double value() const { return m_value * (m_max - m_min) + m_min; } + void value(double value); + + virtual bool in_rect(double x, double y) const; + virtual bool on_mouse_button_down(double x, double y); + virtual bool on_mouse_button_up(double x, double y); + virtual bool on_mouse_move(double x, double y, bool button_flag); + virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); + + // Vertex source interface + unsigned num_paths() { return 6; }; + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + void calc_box(); + bool normalize_value(bool preview_value_flag); + + double m_border_width; + double m_border_extra; + double m_text_thickness; + double m_value; + double m_preview_value; + double m_min; + double m_max; + unsigned m_num_steps; + bool m_descending; + char m_label[64]; + double m_xs1; + double m_ys1; + double m_xs2; + double m_ys2; + double m_pdx; + bool m_mouse_move; + double m_vx[32]; + double m_vy[32]; + + ellipse m_ellipse; + + unsigned m_idx; + unsigned m_vertex; + + gsv_text m_text; + conv_stroke<gsv_text> m_text_poly; + path_storage m_storage; + + }; + + + + //----------------------------------------------------------slider_ctrl + template<class ColorT> class slider_ctrl : public slider_ctrl_impl + { + public: + slider_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) : + slider_ctrl_impl(x1, y1, x2, y2, flip_y), + m_background_color(rgba(1.0, 0.9, 0.8)), + m_triangle_color(rgba(0.7, 0.6, 0.6)), + m_text_color(rgba(0.0, 0.0, 0.0)), + m_pointer_preview_color(rgba(0.6, 0.4, 0.4, 0.4)), + m_pointer_color(rgba(0.8, 0.0, 0.0, 0.6)) + { + m_colors[0] = &m_background_color; + m_colors[1] = &m_triangle_color; + m_colors[2] = &m_text_color; + m_colors[3] = &m_pointer_preview_color; + m_colors[4] = &m_pointer_color; + m_colors[5] = &m_text_color; + } + + + void background_color(const ColorT& c) { m_background_color = c; } + void pointer_color(const ColorT& c) { m_pointer_color = c; } + + const ColorT& color(unsigned i) const { return *m_colors[i]; } + + private: + slider_ctrl(const slider_ctrl<ColorT>&); + const slider_ctrl<ColorT>& operator = (const slider_ctrl<ColorT>&); + + ColorT m_background_color; + ColorT m_triangle_color; + ColorT m_text_color; + ColorT m_pointer_preview_color; + ColorT m_pointer_color; + ColorT* m_colors[6]; + }; + + + + + +} + + + +#endif + diff --git a/include/ctrl/agg_spline_ctrl.h b/include/ctrl/agg_spline_ctrl.h new file mode 100644 index 0000000..8477f27 --- /dev/null +++ b/include/ctrl/agg_spline_ctrl.h @@ -0,0 +1,159 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes spline_ctrl_impl, spline_ctrl +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SPLINE_CTRL_INCLUDED +#define AGG_SPLINE_CTRL_INCLUDED + +#include "agg_basics.h" +#include "agg_ellipse.h" +#include "agg_bspline.h" +#include "agg_conv_stroke.h" +#include "agg_path_storage.h" +#include "agg_trans_affine.h" +#include "agg_color_rgba.h" +#include "agg_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + // Class that can be used to create an interactive control to set up + // gamma arrays. + //------------------------------------------------------------------------ + class spline_ctrl_impl : public ctrl + { + public: + spline_ctrl_impl(double x1, double y1, double x2, double y2, + unsigned num_pnt, bool flip_y=false); + + // Set other parameters + void border_width(double t, double extra=0.0); + void curve_width(double t) { m_curve_width = t; } + void point_size(double s) { m_point_size = s; } + + // Event handlers. Just call them if the respective events + // in your system occure. The functions return true if redrawing + // is required. + virtual bool in_rect(double x, double y) const; + virtual bool on_mouse_button_down(double x, double y); + virtual bool on_mouse_button_up(double x, double y); + virtual bool on_mouse_move(double x, double y, bool button_flag); + virtual bool on_arrow_keys(bool left, bool right, bool down, bool up); + + void active_point(int i); + + const double* spline() const { return m_spline_values; } + const int8u* spline8() const { return m_spline_values8; } + double value(double x) const; + void value(unsigned idx, double y); + void point(unsigned idx, double x, double y); + void x(unsigned idx, double x) { m_xp[idx] = x; } + void y(unsigned idx, double y) { m_yp[idx] = y; } + double x(unsigned idx) const { return m_xp[idx]; } + double y(unsigned idx) const { return m_yp[idx]; } + void update_spline(); + + // Vertex soutce interface + unsigned num_paths() { return 5; } + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + void calc_spline_box(); + void calc_curve(); + double calc_xp(unsigned idx); + double calc_yp(unsigned idx); + void set_xp(unsigned idx, double val); + void set_yp(unsigned idx, double val); + + unsigned m_num_pnt; + double m_xp[32]; + double m_yp[32]; + bspline m_spline; + double m_spline_values[256]; + int8u m_spline_values8[256]; + double m_border_width; + double m_border_extra; + double m_curve_width; + double m_point_size; + double m_xs1; + double m_ys1; + double m_xs2; + double m_ys2; + path_storage m_curve_pnt; + conv_stroke<path_storage> m_curve_poly; + ellipse m_ellipse; + unsigned m_idx; + unsigned m_vertex; + double m_vx[32]; + double m_vy[32]; + int m_active_pnt; + int m_move_pnt; + double m_pdx; + double m_pdy; + const trans_affine* m_mtx; + }; + + + template<class ColorT> class spline_ctrl : public spline_ctrl_impl + { + public: + spline_ctrl(double x1, double y1, double x2, double y2, + unsigned num_pnt, bool flip_y=false) : + spline_ctrl_impl(x1, y1, x2, y2, num_pnt, flip_y), + m_background_color(rgba(1.0, 1.0, 0.9)), + m_border_color(rgba(0.0, 0.0, 0.0)), + m_curve_color(rgba(0.0, 0.0, 0.0)), + m_inactive_pnt_color(rgba(0.0, 0.0, 0.0)), + m_active_pnt_color(rgba(1.0, 0.0, 0.0)) + { + m_colors[0] = &m_background_color; + m_colors[1] = &m_border_color; + m_colors[2] = &m_curve_color; + m_colors[3] = &m_inactive_pnt_color; + m_colors[4] = &m_active_pnt_color; + } + + // Set colors + void background_color(const ColorT& c) { m_background_color = c; } + void border_color(const ColorT& c) { m_border_color = c; } + void curve_color(const ColorT& c) { m_curve_color = c; } + void inactive_pnt_color(const ColorT& c) { m_inactive_pnt_color = c; } + void active_pnt_color(const ColorT& c) { m_active_pnt_color = c; } + const ColorT& color(unsigned i) const { return *m_colors[i]; } + + private: + spline_ctrl(const spline_ctrl<ColorT>&); + const spline_ctrl<ColorT>& operator = (const spline_ctrl<ColorT>&); + + ColorT m_background_color; + ColorT m_border_color; + ColorT m_curve_color; + ColorT m_inactive_pnt_color; + ColorT m_active_pnt_color; + ColorT* m_colors[5]; + }; + + + + +} + + +#endif diff --git a/include/platform/Makefile.am b/include/platform/Makefile.am new file mode 100644 index 0000000..15b5b44 --- /dev/null +++ b/include/platform/Makefile.am @@ -0,0 +1,4 @@ +EXTRA_DIST=win32/agg_win32_bmp.h \ + mac/agg_mac_pmap.h +myincludedir = $(includedir)/agg2/platform +myinclude_HEADERS = agg_platform_support.h diff --git a/include/platform/agg_platform_support.h b/include/platform/agg_platform_support.h new file mode 100644 index 0000000..722b009 --- /dev/null +++ b/include/platform/agg_platform_support.h @@ -0,0 +1,686 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class platform_support +// +// It's not a part of the AGG library, it's just a helper class to create +// interactive demo examples. Since the examples should not be too complex +// this class is provided to support some very basic interactive graphical +// functionality, such as putting the rendered image to the window, simple +// keyboard and mouse input, window resizing, setting the window title, +// and catching the "idle" events. +// +// The idea is to have a single header file that does not depend on any +// platform (I hate these endless #ifdef/#elif/#elif.../#endif) and a number +// of different implementations depending on the concrete platform. +// The most popular platforms are: +// +// Windows-32 API +// X-Window API +// SDL library (see http://www.libsdl.org/) +// MacOS C/C++ API +// +// This file does not include any system dependent .h files such as +// windows.h or X11.h, so, your demo applications do not depend on the +// platform. The only file that can #include system dependend headers +// is the implementation file agg_platform_support.cpp. Different +// implementations are placed in different directories, such as +// ~/agg/src/platform/win32 +// ~/agg/src/platform/sdl +// ~/agg/src/platform/X11 +// and so on. +// +// All the system dependent stuff sits in the platform_specific +// class which is forward-declared here but not defined. +// The platform_support class has just a pointer to it and it's +// the responsibility of the implementation to create/delete it. +// This class being defined in the implementation file can have +// any platform dependent stuff such as HWND, X11 Window and so on. +// +//---------------------------------------------------------------------------- + + +#ifndef AGG_PLATFORM_SUPPORT_INCLUDED +#define AGG_PLATFORM_SUPPORT_INCLUDED + + +#include "agg_basics.h" +#include "agg_rendering_buffer.h" +#include "agg_trans_viewport.h" +#include "ctrl/agg_ctrl.h" + +namespace agg +{ + + //----------------------------------------------------------window_flag_e + // These are flags used in method init(). Not all of them are + // applicable on different platforms, for example the win32_api + // cannot use a hardware buffer (window_hw_buffer). + // The implementation should simply ignore unsupported flags. + enum window_flag_e + { + window_resize = 1, + window_hw_buffer = 2, + window_keep_aspect_ratio = 4, + window_process_all_keys = 8 + }; + + //-----------------------------------------------------------pix_format_e + // Possible formats of the rendering buffer. Initially I thought that it's + // reasonable to create the buffer and the rendering functions in + // accordance with the native pixel format of the system because it + // would have no overhead for pixel format conersion. + // But eventually I came to a conclusion that having a possibility to + // convert pixel formats on demand is a good idea. First, it was X11 where + // there lots of different formats and visuals and it would be great to + // render everything in, say, RGB-24 and display it automatically without + // any additional efforts. The second reason is to have a possibility to + // debug renderers for different pixel formats and colorspaces having only + // one computer and one system. + // + // This stuff is not included into the basic AGG functionality because the + // number of supported pixel formats (and/or colorspaces) can be great and + // if one needs to add new format it would be good only to add new + // rendering files without having to modify any existing ones (a general + // principle of incapsulation and isolation). + // + // Using a particular pixel format doesn't obligatory mean the necessity + // of software conversion. For example, win32 API can natively display + // gray8, 15-bit RGB, 24-bit BGR, and 32-bit BGRA formats. + // This list can be (and will be!) extended in future. + enum pix_format_e + { + pix_format_undefined = 0, // By default. No conversions are applied + pix_format_bw, // 1 bit per color B/W + pix_format_gray8, // Simple 256 level grayscale + pix_format_sgray8, // Simple 256 level grayscale (sRGB) + pix_format_gray16, // Simple 65535 level grayscale + pix_format_gray32, // Grayscale, one 32-bit float per pixel + pix_format_rgb555, // 15 bit rgb. Depends on the byte ordering! + pix_format_rgb565, // 16 bit rgb. Depends on the byte ordering! + pix_format_rgbAAA, // 30 bit rgb. Depends on the byte ordering! + pix_format_rgbBBA, // 32 bit rgb. Depends on the byte ordering! + pix_format_bgrAAA, // 30 bit bgr. Depends on the byte ordering! + pix_format_bgrABB, // 32 bit bgr. Depends on the byte ordering! + pix_format_rgb24, // R-G-B, one byte per color component + pix_format_srgb24, // R-G-B, one byte per color component (sRGB) + pix_format_bgr24, // B-G-R, one byte per color component + pix_format_sbgr24, // B-G-R, native win32 BMP format (sRGB) + pix_format_rgba32, // R-G-B-A, one byte per color component + pix_format_srgba32, // R-G-B-A, one byte per color component (sRGB) + pix_format_argb32, // A-R-G-B, native MAC format + pix_format_sargb32, // A-R-G-B, native MAC format (sRGB) + pix_format_abgr32, // A-B-G-R, one byte per color component + pix_format_sabgr32, // A-B-G-R, one byte per color component (sRGB) + pix_format_bgra32, // B-G-R-A, native win32 BMP format + pix_format_sbgra32, // B-G-R-A, native win32 BMP format (sRGB) + pix_format_rgb48, // R-G-B, 16 bits per color component + pix_format_bgr48, // B-G-R, native win32 BMP format. + pix_format_rgb96, // R-G-B, one 32-bit float per color component + pix_format_bgr96, // B-G-R, one 32-bit float per color component + pix_format_rgba64, // R-G-B-A, 16 bits byte per color component + pix_format_argb64, // A-R-G-B, native MAC format + pix_format_abgr64, // A-B-G-R, one byte per color component + pix_format_bgra64, // B-G-R-A, native win32 BMP format + pix_format_rgba128, // R-G-B-A, one 32-bit float per color component + pix_format_argb128, // A-R-G-B, one 32-bit float per color component + pix_format_abgr128, // A-B-G-R, one 32-bit float per color component + pix_format_bgra128, // B-G-R-A, one 32-bit float per color component + + end_of_pix_formats + }; + + //-------------------------------------------------------------input_flag_e + // Mouse and keyboard flags. They can be different on different platforms + // and the ways they are obtained are also different. But in any case + // the system dependent flags should be mapped into these ones. The meaning + // of that is as follows. For example, if kbd_ctrl is set it means that the + // ctrl key is pressed and being held at the moment. They are also used in + // the overridden methods such as on_mouse_move(), on_mouse_button_down(), + // on_mouse_button_dbl_click(), on_mouse_button_up(), on_key(). + // In the method on_mouse_button_up() the mouse flags have different + // meaning. They mean that the respective button is being released, but + // the meaning of the keyboard flags remains the same. + // There's absolut minimal set of flags is used because they'll be most + // probably supported on different platforms. Even the mouse_right flag + // is restricted because Mac's mice have only one button, but AFAIK + // it can be simulated with holding a special key on the keydoard. + enum input_flag_e + { + mouse_left = 1, + mouse_right = 2, + kbd_shift = 4, + kbd_ctrl = 8 + }; + + //--------------------------------------------------------------key_code_e + // Keyboard codes. There's also a restricted set of codes that are most + // probably supported on different platforms. Any platform dependent codes + // should be converted into these ones. There're only those codes are + // defined that cannot be represented as printable ASCII-characters. + // All printable ASCII-set can be used in a regular C/C++ manner: + // ' ', 'A', '0' '+' and so on. + // Since the class is used for creating very simple demo-applications + // we don't need very rich possibilities here, just basic ones. + // Actually the numeric key codes are taken from the SDL library, so, + // the implementation of the SDL support does not require any mapping. + enum key_code_e + { + // ASCII set. Should be supported everywhere + key_backspace = 8, + key_tab = 9, + key_clear = 12, + key_return = 13, + key_pause = 19, + key_escape = 27, + + // Keypad + key_delete = 127, + key_kp0 = 256, + key_kp1 = 257, + key_kp2 = 258, + key_kp3 = 259, + key_kp4 = 260, + key_kp5 = 261, + key_kp6 = 262, + key_kp7 = 263, + key_kp8 = 264, + key_kp9 = 265, + key_kp_period = 266, + key_kp_divide = 267, + key_kp_multiply = 268, + key_kp_minus = 269, + key_kp_plus = 270, + key_kp_enter = 271, + key_kp_equals = 272, + + // Arrow-keys and stuff + key_up = 273, + key_down = 274, + key_right = 275, + key_left = 276, + key_insert = 277, + key_home = 278, + key_end = 279, + key_page_up = 280, + key_page_down = 281, + + // Functional keys. You'd better avoid using + // f11...f15 in your applications if you want + // the applications to be portable + key_f1 = 282, + key_f2 = 283, + key_f3 = 284, + key_f4 = 285, + key_f5 = 286, + key_f6 = 287, + key_f7 = 288, + key_f8 = 289, + key_f9 = 290, + key_f10 = 291, + key_f11 = 292, + key_f12 = 293, + key_f13 = 294, + key_f14 = 295, + key_f15 = 296, + + // The possibility of using these keys is + // very restricted. Actually it's guaranteed + // only in win32_api and win32_sdl implementations + key_numlock = 300, + key_capslock = 301, + key_scrollock = 302, + + // Phew! + end_of_key_codes + }; + + + //------------------------------------------------------------------------ + // A predeclaration of the platform dependent class. Since we do not + // know anything here the only we can have is just a pointer to this + // class as a data member. It should be created and destroyed explicitly + // in the constructor/destructor of the platform_support class. + // Although the pointer to platform_specific is public the application + // cannot have access to its members or methods since it does not know + // anything about them and it's a perfect incapsulation :-) + class platform_specific; + + + //----------------------------------------------------------ctrl_container + // A helper class that contains pointers to a number of controls. + // This class is used to ease the event handling with controls. + // The implementation should simply call the appropriate methods + // of this class when appropriate events occur. + class ctrl_container + { + enum max_ctrl_e { max_ctrl = 64 }; + + public: + //-------------------------------------------------------------------- + ctrl_container() : m_num_ctrl(0), m_cur_ctrl(-1) {} + + //-------------------------------------------------------------------- + void add(ctrl& c) + { + if(m_num_ctrl < max_ctrl) + { + m_ctrl[m_num_ctrl++] = &c; + } + } + + //-------------------------------------------------------------------- + bool in_rect(double x, double y) + { + unsigned i; + for(i = 0; i < m_num_ctrl; i++) + { + if(m_ctrl[i]->in_rect(x, y)) return true; + } + return false; + } + + //-------------------------------------------------------------------- + bool on_mouse_button_down(double x, double y) + { + unsigned i; + for(i = 0; i < m_num_ctrl; i++) + { + if(m_ctrl[i]->on_mouse_button_down(x, y)) return true; + } + return false; + } + + //-------------------------------------------------------------------- + bool on_mouse_button_up(double x, double y) + { + unsigned i; + bool flag = false; + for(i = 0; i < m_num_ctrl; i++) + { + if(m_ctrl[i]->on_mouse_button_up(x, y)) flag = true; + } + return flag; + } + + //-------------------------------------------------------------------- + bool on_mouse_move(double x, double y, bool button_flag) + { + unsigned i; + for(i = 0; i < m_num_ctrl; i++) + { + if(m_ctrl[i]->on_mouse_move(x, y, button_flag)) return true; + } + return false; + } + + //-------------------------------------------------------------------- + bool on_arrow_keys(bool left, bool right, bool down, bool up) + { + if(m_cur_ctrl >= 0) + { + return m_ctrl[m_cur_ctrl]->on_arrow_keys(left, right, down, up); + } + return false; + } + + //-------------------------------------------------------------------- + bool set_cur(double x, double y) + { + unsigned i; + for(i = 0; i < m_num_ctrl; i++) + { + if(m_ctrl[i]->in_rect(x, y)) + { + if(m_cur_ctrl != int(i)) + { + m_cur_ctrl = i; + return true; + } + return false; + } + } + if(m_cur_ctrl != -1) + { + m_cur_ctrl = -1; + return true; + } + return false; + } + + private: + ctrl* m_ctrl[max_ctrl]; + unsigned m_num_ctrl; + int m_cur_ctrl; + }; + + + + //---------------------------------------------------------platform_support + // This class is a base one to the apllication classes. It can be used + // as follows: + // + // class the_application : public agg::platform_support + // { + // public: + // the_application(unsigned bpp, bool flip_y) : + // platform_support(bpp, flip_y) + // . . . + // + // //override stuff . . . + // virtual void on_init() + // { + // . . . + // } + // + // virtual void on_draw() + // { + // . . . + // } + // + // virtual void on_resize(int sx, int sy) + // { + // . . . + // } + // // . . . and so on, see virtual functions + // + // + // //any your own stuff . . . + // }; + // + // + // int agg_main(int argc, char* argv[]) + // { + // the_application app(pix_format_rgb24, true); + // app.caption("AGG Example. Lion"); + // + // if(app.init(500, 400, agg::window_resize)) + // { + // return app.run(); + // } + // return 1; + // } + // + // The reason to have agg_main() instead of just main() is that SDL + // for Windows requires including SDL.h if you define main(). Since + // the demo applications cannot rely on any platform/library specific + // stuff it's impossible to include SDL.h into the application files. + // The demo applications are simple and their use is restricted, so, + // this approach is quite reasonable. + // + class platform_support + { + public: + enum max_images_e { max_images = 16 }; + + // format - see enum pix_format_e {}; + // flip_y - true if you want to have the Y-axis flipped vertically. + platform_support(pix_format_e format, bool flip_y); + virtual ~platform_support(); + + // Setting the windows caption (title). Should be able + // to be called at least before calling init(). + // It's perfect if they can be called anytime. + void caption(const char* cap); + const char* caption() const { return m_caption; } + + //-------------------------------------------------------------------- + // These 3 methods handle working with images. The image + // formats are the simplest ones, such as .BMP in Windows or + // .ppm in Linux. In the applications the names of the files + // should not have any file extensions. Method load_img() can + // be called before init(), so, the application could be able + // to determine the initial size of the window depending on + // the size of the loaded image. + // The argument "idx" is the number of the image 0...max_images-1 + bool load_img(unsigned idx, const char* file); + bool save_img(unsigned idx, const char* file); + bool create_img(unsigned idx, unsigned width=0, unsigned height=0); + + //-------------------------------------------------------------------- + // init() and run(). See description before the class for details. + // The necessity of calling init() after creation is that it's + // impossible to call the overridden virtual function (on_init()) + // from the constructor. On the other hand it's very useful to have + // some on_init() event handler when the window is created but + // not yet displayed. The rbuf_window() method (see below) is + // accessible from on_init(). + bool init(unsigned width, unsigned height, unsigned flags); + int run(); + + //-------------------------------------------------------------------- + // The very same parameters that were used in the constructor + pix_format_e format() const { return m_format; } + bool flip_y() const { return m_flip_y; } + unsigned bpp() const { return m_bpp; } + + //-------------------------------------------------------------------- + // The following provides a very simple mechanism of doing someting + // in background. It's not multithreading. When wait_mode is true + // the class waits for the events and it does not ever call on_idle(). + // When it's false it calls on_idle() when the event queue is empty. + // The mode can be changed anytime. This mechanism is satisfactory + // to create very simple animations. + bool wait_mode() const { return m_wait_mode; } + void wait_mode(bool wait_mode) { m_wait_mode = wait_mode; } + + //-------------------------------------------------------------------- + // These two functions control updating of the window. + // force_redraw() is an analog of the Win32 InvalidateRect() function. + // Being called it sets a flag (or sends a message) which results + // in calling on_draw() and updating the content of the window + // when the next event cycle comes. + // update_window() results in just putting immediately the content + // of the currently rendered buffer to the window without calling + // on_draw(). + void force_redraw(); + void update_window(); + + //-------------------------------------------------------------------- + // So, finally, how to draw anythig with AGG? Very simple. + // rbuf_window() returns a reference to the main rendering + // buffer which can be attached to any rendering class. + // rbuf_img() returns a reference to the previously created + // or loaded image buffer (see load_img()). The image buffers + // are not displayed directly, they should be copied to or + // combined somehow with the rbuf_window(). rbuf_window() is + // the only buffer that can be actually displayed. + rendering_buffer& rbuf_window() { return m_rbuf_window; } + rendering_buffer& rbuf_img(unsigned idx) { return m_rbuf_img[idx]; } + + + //-------------------------------------------------------------------- + // Returns file extension used in the implementation for the particular + // system. + const char* img_ext() const; + + //-------------------------------------------------------------------- + void copy_img_to_window(unsigned idx) + { + if(idx < max_images && rbuf_img(idx).buf()) + { + rbuf_window().copy_from(rbuf_img(idx)); + } + } + + //-------------------------------------------------------------------- + void copy_window_to_img(unsigned idx) + { + if(idx < max_images) + { + create_img(idx, rbuf_window().width(), rbuf_window().height()); + rbuf_img(idx).copy_from(rbuf_window()); + } + } + + //-------------------------------------------------------------------- + void copy_img_to_img(unsigned idx_to, unsigned idx_from) + { + if(idx_from < max_images && + idx_to < max_images && + rbuf_img(idx_from).buf()) + { + create_img(idx_to, + rbuf_img(idx_from).width(), + rbuf_img(idx_from).height()); + rbuf_img(idx_to).copy_from(rbuf_img(idx_from)); + } + } + + //-------------------------------------------------------------------- + // Event handlers. They are not pure functions, so you don't have + // to override them all. + // In my demo applications these functions are defined inside + // the the_application class (implicit inlining) which is in general + // very bad practice, I mean vitual inline methods. At least it does + // not make sense. + // But in this case it's quite appropriate bacause we have the only + // instance of the the_application class and it is in the same file + // where this class is defined. + virtual void on_init(); + virtual void on_resize(int sx, int sy); + virtual void on_idle(); + virtual void on_mouse_move(int x, int y, unsigned flags); + virtual void on_mouse_button_down(int x, int y, unsigned flags); + virtual void on_mouse_button_up(int x, int y, unsigned flags); + virtual void on_key(int x, int y, unsigned key, unsigned flags); + virtual void on_ctrl_change(); + virtual void on_draw(); + virtual void on_post_draw(void* raw_handler); + + //-------------------------------------------------------------------- + // Adding control elements. A control element once added will be + // working and reacting to the mouse and keyboard events. Still, you + // will have to render them in the on_draw() using function + // render_ctrl() because platform_support doesn't know anything about + // renderers you use. The controls will be also scaled automatically + // if they provide a proper scaling mechanism (all the controls + // included into the basic AGG package do). + // If you don't need a particular control to be scaled automatically + // call ctrl::no_transform() after adding. + void add_ctrl(ctrl& c) { m_ctrls.add(c); c.transform(m_resize_mtx); } + + //-------------------------------------------------------------------- + // Auxiliary functions. trans_affine_resizing() modifier sets up the resizing + // matrix on the basis of the given width and height and the initial + // width and height of the window. The implementation should simply + // call this function every time when it catches the resizing event + // passing in the new values of width and height of the window. + // Nothing prevents you from "cheating" the scaling matrix if you + // call this function from somewhere with wrong arguments. + // trans_affine_resizing() accessor simply returns current resizing matrix + // which can be used to apply additional scaling of any of your + // stuff when the window is being resized. + // width(), height(), initial_width(), and initial_height() must be + // clear to understand with no comments :-) + void trans_affine_resizing(int width, int height) + { + if(m_window_flags & window_keep_aspect_ratio) + { + //double sx = double(width) / double(m_initial_width); + //double sy = double(height) / double(m_initial_height); + //if(sy < sx) sx = sy; + //m_resize_mtx = trans_affine_scaling(sx, sx); + trans_viewport vp; + vp.preserve_aspect_ratio(0.5, 0.5, aspect_ratio_meet); + vp.device_viewport(0, 0, width, height); + vp.world_viewport(0, 0, m_initial_width, m_initial_height); + m_resize_mtx = vp.to_affine(); + } + else + { + m_resize_mtx = trans_affine_scaling( + double(width) / double(m_initial_width), + double(height) / double(m_initial_height)); + } + } + trans_affine& trans_affine_resizing() { return m_resize_mtx; } + const trans_affine& trans_affine_resizing() const { return m_resize_mtx; } + double width() const { return m_rbuf_window.width(); } + double height() const { return m_rbuf_window.height(); } + double initial_width() const { return m_initial_width; } + double initial_height() const { return m_initial_height; } + unsigned window_flags() const { return m_window_flags; } + + //-------------------------------------------------------------------- + // Get raw display handler depending on the system. + // For win32 its an HDC, for other systems it can be a pointer to some + // structure. See the implementation files for detals. + // It's provided "as is", so, first you should check if it's not null. + // If it's null the raw_display_handler is not supported. Also, there's + // no guarantee that this function is implemented, so, in some + // implementations you may have simply an unresolved symbol when linking. + void* raw_display_handler(); + + //-------------------------------------------------------------------- + // display message box or print the message to the console + // (depending on implementation) + void message(const char* msg); + + //-------------------------------------------------------------------- + // Stopwatch functions. Function elapsed_time() returns time elapsed + // since the latest start_timer() invocation in millisecods. + // The resolutoin depends on the implementation. + // In Win32 it uses QueryPerformanceFrequency() / QueryPerformanceCounter(). + void start_timer(); + double elapsed_time() const; + + //-------------------------------------------------------------------- + // Get the full file name. In most cases it simply returns + // file_name. As it's appropriate in many systems if you open + // a file by its name without specifying the path, it tries to + // open it in the current directory. The demos usually expect + // all the supplementary files to be placed in the current + // directory, that is usually coincides with the directory where + // the executable is. However, in some systems (BeOS) it's not so. + // For those kinds of systems full_file_name() can help access files + // preserving commonly used policy. + // So, it's a good idea to use in the demos the following: + // FILE* fd = fopen(full_file_name("some.file"), "r"); + // instead of + // FILE* fd = fopen("some.file", "r"); + const char* full_file_name(const char* file_name); + + public: + platform_specific* m_specific; + ctrl_container m_ctrls; + + // Sorry, I'm too tired to describe the private + // data membders. See the implementations for different + // platforms for details. + private: + platform_support(const platform_support&); + const platform_support& operator = (const platform_support&); + + pix_format_e m_format; + unsigned m_bpp; + rendering_buffer m_rbuf_window; + rendering_buffer m_rbuf_img[max_images]; + unsigned m_window_flags; + bool m_wait_mode; + bool m_flip_y; + char m_caption[256]; + int m_initial_width; + int m_initial_height; + trans_affine m_resize_mtx; + }; + + +} + + + +#endif + diff --git a/include/platform/mac/agg_mac_pmap.h b/include/platform/mac/agg_mac_pmap.h new file mode 100644 index 0000000..c71091d --- /dev/null +++ b/include/platform/mac/agg_mac_pmap.h @@ -0,0 +1,86 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) +// Copyright (C) 2002 Hansruedi Baer (MacOS support) +// +// 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 +// baer@karto.baug.eth.ch +//---------------------------------------------------------------------------- +// +// class pixel_map +// +//---------------------------------------------------------------------------- +#ifndef AGG_MAC_PMAP_INCLUDED +#define AGG_MAC_PMAP_INCLUDED + + +#include <Carbon.h> + + +namespace agg +{ + enum org_e + { + org_mono8 = 8, + org_color16 = 16, + org_color24 = 24, + org_color32 = 32 + }; + + class pixel_map + { + public: + ~pixel_map(); + pixel_map(); + + public: + void destroy(); + void create(unsigned width, + unsigned height, + org_e org, + unsigned clear_val=255); + + void clear(unsigned clear_val=255); + bool load_from_qt(const char* filename); + bool save_as_qt(const char* filename) const; + + void draw(WindowRef window, + const Rect* device_rect=0, + const Rect* bmp_rect=0) const; + void draw(WindowRef window, int x, int y, double scale=1.0) const; + void blend(WindowRef window, + const Rect* device_rect=0, + const Rect* bmp_rect=0) const; + void blend(WindowRef window, int x, int y, double scale=1.0) const; + + unsigned char* buf(); + unsigned width() const; + unsigned height() const; + int row_bytes() const; + unsigned bpp() const { return m_bpp; } + + //Auxiliary static functions + static unsigned calc_row_len(unsigned width, unsigned bits_per_pixel); + private: + pixel_map(const pixel_map&); + const pixel_map& operator = (const pixel_map&); + + private: + GWorldPtr m_pmap; + unsigned char* m_buf; + unsigned m_bpp; + unsigned m_img_size; + }; + +} + + +#endif diff --git a/include/platform/win32/agg_win32_bmp.h b/include/platform/win32/agg_win32_bmp.h new file mode 100644 index 0000000..961a44d --- /dev/null +++ b/include/platform/win32/agg_win32_bmp.h @@ -0,0 +1,116 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class pixel_map +// +//---------------------------------------------------------------------------- +#ifndef AGG_WIN32_BMP_INCLUDED +#define AGG_WIN32_BMP_INCLUDED + + +#include <windows.h> + + +namespace agg +{ + enum org_e + { + org_mono8 = 8, + org_color16 = 16, + org_color24 = 24, + org_color32 = 32, + org_color48 = 48, + org_color64 = 64 + }; + + class pixel_map + { + public: + ~pixel_map(); + pixel_map(); + + public: + void destroy(); + void create(unsigned width, + unsigned height, + org_e org, + unsigned clear_val=256); + HBITMAP create_dib_section(HDC h_dc, + unsigned width, + unsigned height, + org_e org, + unsigned clear_val=256); + + void clear(unsigned clear_val=256); + void attach_to_bmp(BITMAPINFO* bmp); + BITMAPINFO* bitmap_info() { return m_bmp; } + bool load_from_bmp(FILE* fd); + bool save_as_bmp(FILE* fd) const; + bool load_from_bmp(const char* filename); + bool save_as_bmp(const char* filename) const; + + void draw(HDC h_dc, + const RECT* device_rect=0, + const RECT* bmp_rect=0) const; + void draw(HDC h_dc, int x, int y, double scale=1.0) const; + + void blend(HDC h_dc, + const RECT* device_rect=0, + const RECT* bmp_rect=0) const; + void blend(HDC h_dc, int x, int y, double scale=1.0) const; + + + unsigned char* buf(); + unsigned width() const; + unsigned height() const; + int stride() const; + unsigned bpp() const { return m_bpp; } + + //Auxiliary static functions + static unsigned calc_full_size(BITMAPINFO *bmp); + static unsigned calc_header_size(BITMAPINFO *bmp); + static unsigned calc_palette_size(unsigned clr_used, + unsigned bits_per_pixel); + static unsigned calc_palette_size(BITMAPINFO *bmp); + static unsigned char* calc_img_ptr(BITMAPINFO *bmp); + static BITMAPINFO* create_bitmap_info(unsigned width, + unsigned height, + unsigned bits_per_pixel); + static void create_gray_scale_palette(BITMAPINFO *bmp); + static unsigned calc_row_len(unsigned width, unsigned bits_per_pixel); + + private: + pixel_map(const pixel_map&); + const pixel_map& operator = (const pixel_map&); + void create_from_bmp(BITMAPINFO *bmp); + + HBITMAP create_dib_section_from_args(HDC h_dc, + unsigned width, + unsigned height, + unsigned bits_per_pixel); + + private: + BITMAPINFO* m_bmp; + unsigned char* m_buf; + unsigned m_bpp; + bool m_is_internal; + unsigned m_img_size; + unsigned m_full_size; + }; + +} + + +#endif diff --git a/include/util/Makefile.am b/include/util/Makefile.am new file mode 100644 index 0000000..e197c3d --- /dev/null +++ b/include/util/Makefile.am @@ -0,0 +1,2 @@ +myincludedir = $(includedir)/agg2/util +myinclude_HEADERS = agg_color_conv.h agg_color_conv_rgb8.h agg_color_conv_rgb16.h diff --git a/include/util/agg_color_conv.h b/include/util/agg_color_conv.h new file mode 100644 index 0000000..9f38b3b --- /dev/null +++ b/include/util/agg_color_conv.h @@ -0,0 +1,128 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Conversion from one colorspace/pixel format to another +// +//---------------------------------------------------------------------------- + +#ifndef AGG_COLOR_CONV_INCLUDED +#define AGG_COLOR_CONV_INCLUDED + +#include <cstring> +#include "agg_basics.h" +#include "agg_rendering_buffer.h" + + + + +namespace agg +{ + + //--------------------------------------------------------------color_conv + template<class RenBuf, class CopyRow> + void color_conv(RenBuf* dst, const RenBuf* src, CopyRow copy_row_functor) + { + unsigned width = src->width(); + unsigned height = src->height(); + + if(dst->width() < width) width = dst->width(); + if(dst->height() < height) height = dst->height(); + + if(width) + { + unsigned y; + for(y = 0; y < height; y++) + { + copy_row_functor(dst->row_ptr(0, y, width), + src->row_ptr(y), + width); + } + } + } + + + //---------------------------------------------------------color_conv_row + template<class CopyRow> + void color_conv_row(int8u* dst, + const int8u* src, + unsigned width, + CopyRow copy_row_functor) + { + copy_row_functor(dst, src, width); + } + + + //---------------------------------------------------------color_conv_same + template<int BPP> class color_conv_same + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + std::memmove(dst, src, width*BPP); + } + }; + + + // Generic pixel converter. + template<class DstFormat, class SrcFormat> + struct conv_pixel + { + void operator()(void* dst, const void* src) const + { + // Read a pixel from the source format and write it to the destination format. + DstFormat::write_plain_color(dst, SrcFormat::read_plain_color(src)); + } + }; + + // Generic row converter. Uses conv_pixel to convert individual pixels. + template<class DstFormat, class SrcFormat> + struct conv_row + { + void operator()(void* dst, const void* src, unsigned width) const + { + conv_pixel<DstFormat, SrcFormat> conv; + do + { + conv(dst, src); + dst = (int8u*)dst + DstFormat::pix_width; + src = (int8u*)src + SrcFormat::pix_width; + } + while (--width); + } + }; + + // Specialization for case where source and destination formats are identical. + template<class Format> + struct conv_row<Format, Format> + { + void operator()(void* dst, const void* src, unsigned width) const + { + std::memmove(dst, src, width * Format::pix_width); + } + }; + + // Top-level conversion function, converts one pixel format to any other. + template<class DstFormat, class SrcFormat, class RenBuf> + void convert(RenBuf* dst, const RenBuf* src) + { + color_conv(dst, src, conv_row<DstFormat, SrcFormat>()); + } +} + + + +#endif diff --git a/include/util/agg_color_conv_rgb16.h b/include/util/agg_color_conv_rgb16.h new file mode 100644 index 0000000..aaa4132 --- /dev/null +++ b/include/util/agg_color_conv_rgb16.h @@ -0,0 +1,285 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// This part of the library has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +// +// A set of functors used with color_conv(). See file agg_color_conv.h +// These functors can convert images with up to 8 bits per component. +// Use convertors in the following way: +// +// agg::color_conv(dst, src, agg::color_conv_XXXX_to_YYYY()); +//---------------------------------------------------------------------------- + +#ifndef AGG_COLOR_CONV_RGB16_INCLUDED +#define AGG_COLOR_CONV_RGB16_INCLUDED + +#include "agg_basics.h" +#include "agg_color_conv.h" + +namespace agg +{ + + //-------------------------------------------------color_conv_gray16_to_gray8 + class color_conv_gray16_to_gray8 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + int16u* s = (int16u*)src; + do + { + *dst++ = *s++ >> 8; + } + while(--width); + } + }; + + + //-----------------------------------------------------color_conv_rgb24_rgb48 + template<int I1, int I3> class color_conv_rgb24_rgb48 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + int16u* d = (int16u*)dst; + do + { + *d++ = (src[I1] << 8) | src[I1]; + *d++ = (src[1] << 8) | src[1] ; + *d++ = (src[I3] << 8) | src[I3]; + src += 3; + } + while(--width); + } + }; + + typedef color_conv_rgb24_rgb48<0,2> color_conv_rgb24_to_rgb48; + typedef color_conv_rgb24_rgb48<0,2> color_conv_bgr24_to_bgr48; + typedef color_conv_rgb24_rgb48<2,0> color_conv_rgb24_to_bgr48; + typedef color_conv_rgb24_rgb48<2,0> color_conv_bgr24_to_rgb48; + + + //-----------------------------------------------------color_conv_rgb24_rgb48 + template<int I1, int I3> class color_conv_rgb48_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + const int16u* s = (const int16u*)src; + do + { + *dst++ = s[I1] >> 8; + *dst++ = s[1] >> 8; + *dst++ = s[I3] >> 8; + s += 3; + } + while(--width); + } + }; + + typedef color_conv_rgb48_rgb24<0,2> color_conv_rgb48_to_rgb24; + typedef color_conv_rgb48_rgb24<0,2> color_conv_bgr48_to_bgr24; + typedef color_conv_rgb48_rgb24<2,0> color_conv_rgb48_to_bgr24; + typedef color_conv_rgb48_rgb24<2,0> color_conv_bgr48_to_rgb24; + + + //----------------------------------------------color_conv_rgbAAA_rgb24 + template<int R, int B> class color_conv_rgbAAA_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int32u rgb = *(int32u*)src; + dst[R] = int8u(rgb >> 22); + dst[1] = int8u(rgb >> 12); + dst[B] = int8u(rgb >> 2); + src += 4; + dst += 3; + } + while(--width); + } + }; + + typedef color_conv_rgbAAA_rgb24<0,2> color_conv_rgbAAA_to_rgb24; + typedef color_conv_rgbAAA_rgb24<2,0> color_conv_rgbAAA_to_bgr24; + typedef color_conv_rgbAAA_rgb24<2,0> color_conv_bgrAAA_to_rgb24; + typedef color_conv_rgbAAA_rgb24<0,2> color_conv_bgrAAA_to_bgr24; + + + //----------------------------------------------color_conv_rgbBBA_rgb24 + template<int R, int B> class color_conv_rgbBBA_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int32u rgb = *(int32u*)src; + dst[R] = int8u(rgb >> 24); + dst[1] = int8u(rgb >> 13); + dst[B] = int8u(rgb >> 2); + src += 4; + dst += 3; + } + while(--width); + } + }; + + typedef color_conv_rgbBBA_rgb24<0,2> color_conv_rgbBBA_to_rgb24; + typedef color_conv_rgbBBA_rgb24<2,0> color_conv_rgbBBA_to_bgr24; + + + //----------------------------------------------color_conv_bgrABB_rgb24 + template<int B, int R> class color_conv_bgrABB_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int32u bgr = *(int32u*)src; + dst[R] = int8u(bgr >> 3); + dst[1] = int8u(bgr >> 14); + dst[B] = int8u(bgr >> 24); + src += 4; + dst += 3; + } + while(--width); + } + }; + + typedef color_conv_bgrABB_rgb24<2,0> color_conv_bgrABB_to_rgb24; + typedef color_conv_bgrABB_rgb24<0,2> color_conv_bgrABB_to_bgr24; + + + //-------------------------------------------------color_conv_rgba64_rgba32 + template<int I1, int I2, int I3, int I4> class color_conv_rgba64_rgba32 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *dst++ = int8u(((int16u*)src)[I1] >> 8); + *dst++ = int8u(((int16u*)src)[I2] >> 8); + *dst++ = int8u(((int16u*)src)[I3] >> 8); + *dst++ = int8u(((int16u*)src)[I4] >> 8); + src += 8; + } + while(--width); + } + }; + + //------------------------------------------------------------------------ + typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_rgba64_to_rgba32; //----color_conv_rgba64_to_rgba32 + typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_argb64_to_argb32; //----color_conv_argb64_to_argb32 + typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_bgra64_to_bgra32; //----color_conv_bgra64_to_bgra32 + typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_abgr64_to_abgr32; //----color_conv_abgr64_to_abgr32 + typedef color_conv_rgba64_rgba32<0,3,2,1> color_conv_argb64_to_abgr32; //----color_conv_argb64_to_abgr32 + typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_argb64_to_bgra32; //----color_conv_argb64_to_bgra32 + typedef color_conv_rgba64_rgba32<1,2,3,0> color_conv_argb64_to_rgba32; //----color_conv_argb64_to_rgba32 + typedef color_conv_rgba64_rgba32<3,0,1,2> color_conv_bgra64_to_abgr32; //----color_conv_bgra64_to_abgr32 + typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_bgra64_to_argb32; //----color_conv_bgra64_to_argb32 + typedef color_conv_rgba64_rgba32<2,1,0,3> color_conv_bgra64_to_rgba32; //----color_conv_bgra64_to_rgba32 + typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_rgba64_to_abgr32; //----color_conv_rgba64_to_abgr32 + typedef color_conv_rgba64_rgba32<3,0,1,2> color_conv_rgba64_to_argb32; //----color_conv_rgba64_to_argb32 + typedef color_conv_rgba64_rgba32<2,1,0,3> color_conv_rgba64_to_bgra32; //----color_conv_rgba64_to_bgra32 + typedef color_conv_rgba64_rgba32<0,3,2,1> color_conv_abgr64_to_argb32; //----color_conv_abgr64_to_argb32 + typedef color_conv_rgba64_rgba32<1,2,3,0> color_conv_abgr64_to_bgra32; //----color_conv_abgr64_to_bgra32 + typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_abgr64_to_rgba32; //----color_conv_abgr64_to_rgba32 + + + + //--------------------------------------------color_conv_rgb24_rgba64 + template<int I1, int I2, int I3, int A> class color_conv_rgb24_rgba64 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + int16u* d = (int16u*)dst; + do + { + d[I1] = (src[0] << 8) | src[0]; + d[I2] = (src[1] << 8) | src[1]; + d[I3] = (src[2] << 8) | src[2]; + d[A] = 65535; + d += 4; + src += 3; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb24_rgba64<1,2,3,0> color_conv_rgb24_to_argb64; //----color_conv_rgb24_to_argb64 + typedef color_conv_rgb24_rgba64<3,2,1,0> color_conv_rgb24_to_abgr64; //----color_conv_rgb24_to_abgr64 + typedef color_conv_rgb24_rgba64<2,1,0,3> color_conv_rgb24_to_bgra64; //----color_conv_rgb24_to_bgra64 + typedef color_conv_rgb24_rgba64<0,1,2,3> color_conv_rgb24_to_rgba64; //----color_conv_rgb24_to_rgba64 + typedef color_conv_rgb24_rgba64<3,2,1,0> color_conv_bgr24_to_argb64; //----color_conv_bgr24_to_argb64 + typedef color_conv_rgb24_rgba64<1,2,3,0> color_conv_bgr24_to_abgr64; //----color_conv_bgr24_to_abgr64 + typedef color_conv_rgb24_rgba64<0,1,2,3> color_conv_bgr24_to_bgra64; //----color_conv_bgr24_to_bgra64 + typedef color_conv_rgb24_rgba64<2,1,0,3> color_conv_bgr24_to_rgba64; //----color_conv_bgr24_to_rgba64 + + + template<int R, int B> class color_conv_rgb24_gray16 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + int16u* d = (int16u*)dst; + do + { + *d++ = src[R]*77 + src[1]*150 + src[B]*29; + src += 3; + } + while(--width); + } + }; + + typedef color_conv_rgb24_gray16<0,2> color_conv_rgb24_to_gray16; + typedef color_conv_rgb24_gray16<2,0> color_conv_bgr24_to_gray16; + + +} + + +#endif diff --git a/include/util/agg_color_conv_rgb8.h b/include/util/agg_color_conv_rgb8.h new file mode 100644 index 0000000..609460d --- /dev/null +++ b/include/util/agg_color_conv_rgb8.h @@ -0,0 +1,476 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// A set of functors used with color_conv(). See file agg_color_conv.h +// These functors can convert images with up to 8 bits per component. +// Use convertors in the following way: +// +// agg::color_conv(dst, src, agg::color_conv_XXXX_to_YYYY()); +// whare XXXX and YYYY can be any of: +// rgb24 +// bgr24 +// rgba32 +// abgr32 +// argb32 +// bgra32 +// rgb555 +// rgb565 +//---------------------------------------------------------------------------- + +#ifndef AGG_COLOR_CONV_RGB8_INCLUDED +#define AGG_COLOR_CONV_RGB8_INCLUDED + +#include "agg_basics.h" +#include "agg_color_conv.h" + +namespace agg +{ + + //-----------------------------------------------------color_conv_rgb24 + class color_conv_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int8u tmp[3]; + tmp[0] = *src++; + tmp[1] = *src++; + tmp[2] = *src++; + *dst++ = tmp[2]; + *dst++ = tmp[1]; + *dst++ = tmp[0]; + } + while(--width); + } + }; + + typedef color_conv_rgb24 color_conv_rgb24_to_bgr24; + typedef color_conv_rgb24 color_conv_bgr24_to_rgb24; + + typedef color_conv_same<3> color_conv_bgr24_to_bgr24; + typedef color_conv_same<3> color_conv_rgb24_to_rgb24; + + + + //------------------------------------------------------color_conv_rgba32 + template<int I1, int I2, int I3, int I4> class color_conv_rgba32 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int8u tmp[4]; + tmp[0] = *src++; + tmp[1] = *src++; + tmp[2] = *src++; + tmp[3] = *src++; + *dst++ = tmp[I1]; + *dst++ = tmp[I2]; + *dst++ = tmp[I3]; + *dst++ = tmp[I4]; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgba32<0,3,2,1> color_conv_argb32_to_abgr32; //----color_conv_argb32_to_abgr32 + typedef color_conv_rgba32<3,2,1,0> color_conv_argb32_to_bgra32; //----color_conv_argb32_to_bgra32 + typedef color_conv_rgba32<1,2,3,0> color_conv_argb32_to_rgba32; //----color_conv_argb32_to_rgba32 + typedef color_conv_rgba32<3,0,1,2> color_conv_bgra32_to_abgr32; //----color_conv_bgra32_to_abgr32 + typedef color_conv_rgba32<3,2,1,0> color_conv_bgra32_to_argb32; //----color_conv_bgra32_to_argb32 + typedef color_conv_rgba32<2,1,0,3> color_conv_bgra32_to_rgba32; //----color_conv_bgra32_to_rgba32 + typedef color_conv_rgba32<3,2,1,0> color_conv_rgba32_to_abgr32; //----color_conv_rgba32_to_abgr32 + typedef color_conv_rgba32<3,0,1,2> color_conv_rgba32_to_argb32; //----color_conv_rgba32_to_argb32 + typedef color_conv_rgba32<2,1,0,3> color_conv_rgba32_to_bgra32; //----color_conv_rgba32_to_bgra32 + typedef color_conv_rgba32<0,3,2,1> color_conv_abgr32_to_argb32; //----color_conv_abgr32_to_argb32 + typedef color_conv_rgba32<1,2,3,0> color_conv_abgr32_to_bgra32; //----color_conv_abgr32_to_bgra32 + typedef color_conv_rgba32<3,2,1,0> color_conv_abgr32_to_rgba32; //----color_conv_abgr32_to_rgba32 + + //------------------------------------------------------------------------ + typedef color_conv_same<4> color_conv_rgba32_to_rgba32; //----color_conv_rgba32_to_rgba32 + typedef color_conv_same<4> color_conv_argb32_to_argb32; //----color_conv_argb32_to_argb32 + typedef color_conv_same<4> color_conv_bgra32_to_bgra32; //----color_conv_bgra32_to_bgra32 + typedef color_conv_same<4> color_conv_abgr32_to_abgr32; //----color_conv_abgr32_to_abgr32 + + + //--------------------------------------------color_conv_rgb24_rgba32 + template<int I1, int I2, int I3, int A> class color_conv_rgb24_rgba32 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + dst[I1] = *src++; + dst[I2] = *src++; + dst[I3] = *src++; + dst[A] = 255; + dst += 4; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb24_rgba32<1,2,3,0> color_conv_rgb24_to_argb32; //----color_conv_rgb24_to_argb32 + typedef color_conv_rgb24_rgba32<3,2,1,0> color_conv_rgb24_to_abgr32; //----color_conv_rgb24_to_abgr32 + typedef color_conv_rgb24_rgba32<2,1,0,3> color_conv_rgb24_to_bgra32; //----color_conv_rgb24_to_bgra32 + typedef color_conv_rgb24_rgba32<0,1,2,3> color_conv_rgb24_to_rgba32; //----color_conv_rgb24_to_rgba32 + typedef color_conv_rgb24_rgba32<3,2,1,0> color_conv_bgr24_to_argb32; //----color_conv_bgr24_to_argb32 + typedef color_conv_rgb24_rgba32<1,2,3,0> color_conv_bgr24_to_abgr32; //----color_conv_bgr24_to_abgr32 + typedef color_conv_rgb24_rgba32<0,1,2,3> color_conv_bgr24_to_bgra32; //----color_conv_bgr24_to_bgra32 + typedef color_conv_rgb24_rgba32<2,1,0,3> color_conv_bgr24_to_rgba32; //----color_conv_bgr24_to_rgba32 + + + + //-------------------------------------------------color_conv_rgba32_rgb24 + template<int I1, int I2, int I3> class color_conv_rgba32_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *dst++ = src[I1]; + *dst++ = src[I2]; + *dst++ = src[I3]; + src += 4; + } + while(--width); + } + }; + + + + //------------------------------------------------------------------------ + typedef color_conv_rgba32_rgb24<1,2,3> color_conv_argb32_to_rgb24; //----color_conv_argb32_to_rgb24 + typedef color_conv_rgba32_rgb24<3,2,1> color_conv_abgr32_to_rgb24; //----color_conv_abgr32_to_rgb24 + typedef color_conv_rgba32_rgb24<2,1,0> color_conv_bgra32_to_rgb24; //----color_conv_bgra32_to_rgb24 + typedef color_conv_rgba32_rgb24<0,1,2> color_conv_rgba32_to_rgb24; //----color_conv_rgba32_to_rgb24 + typedef color_conv_rgba32_rgb24<3,2,1> color_conv_argb32_to_bgr24; //----color_conv_argb32_to_bgr24 + typedef color_conv_rgba32_rgb24<1,2,3> color_conv_abgr32_to_bgr24; //----color_conv_abgr32_to_bgr24 + typedef color_conv_rgba32_rgb24<0,1,2> color_conv_bgra32_to_bgr24; //----color_conv_bgra32_to_bgr24 + typedef color_conv_rgba32_rgb24<2,1,0> color_conv_rgba32_to_bgr24; //----color_conv_rgba32_to_bgr24 + + + //------------------------------------------------color_conv_rgb555_rgb24 + template<int R, int B> class color_conv_rgb555_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + unsigned rgb = *(int16u*)src; + dst[R] = (int8u)((rgb >> 7) & 0xF8); + dst[1] = (int8u)((rgb >> 2) & 0xF8); + dst[B] = (int8u)((rgb << 3) & 0xF8); + src += 2; + dst += 3; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb555_rgb24<2,0> color_conv_rgb555_to_bgr24; //----color_conv_rgb555_to_bgr24 + typedef color_conv_rgb555_rgb24<0,2> color_conv_rgb555_to_rgb24; //----color_conv_rgb555_to_rgb24 + + + //-------------------------------------------------color_conv_rgb24_rgb555 + template<int R, int B> class color_conv_rgb24_rgb555 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *(int16u*)dst = (int16u)(((unsigned(src[R]) << 7) & 0x7C00) | + ((unsigned(src[1]) << 2) & 0x3E0) | + ((unsigned(src[B]) >> 3))); + src += 3; + dst += 2; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb24_rgb555<2,0> color_conv_bgr24_to_rgb555; //----color_conv_bgr24_to_rgb555 + typedef color_conv_rgb24_rgb555<0,2> color_conv_rgb24_to_rgb555; //----color_conv_rgb24_to_rgb555 + + + //-------------------------------------------------color_conv_rgb565_rgb24 + template<int R, int B> class color_conv_rgb565_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + unsigned rgb = *(int16u*)src; + dst[R] = (rgb >> 8) & 0xF8; + dst[1] = (rgb >> 3) & 0xFC; + dst[B] = (rgb << 3) & 0xF8; + src += 2; + dst += 3; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb565_rgb24<2,0> color_conv_rgb565_to_bgr24; //----color_conv_rgb565_to_bgr24 + typedef color_conv_rgb565_rgb24<0,2> color_conv_rgb565_to_rgb24; //----color_conv_rgb565_to_rgb24 + + + //-------------------------------------------------color_conv_rgb24_rgb565 + template<int R, int B> class color_conv_rgb24_rgb565 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *(int16u*)dst = (int16u)(((unsigned(src[R]) << 8) & 0xF800) | + ((unsigned(src[1]) << 3) & 0x7E0) | + ((unsigned(src[B]) >> 3))); + src += 3; + dst += 2; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb24_rgb565<2,0> color_conv_bgr24_to_rgb565; //----color_conv_bgr24_to_rgb565 + typedef color_conv_rgb24_rgb565<0,2> color_conv_rgb24_to_rgb565; //----color_conv_rgb24_to_rgb565 + + + + //-------------------------------------------------color_conv_rgb555_rgba32 + template<int R, int G, int B, int A> class color_conv_rgb555_rgba32 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int rgb = *(int16*)src; + dst[R] = (int8u)((rgb >> 7) & 0xF8); + dst[G] = (int8u)((rgb >> 2) & 0xF8); + dst[B] = (int8u)((rgb << 3) & 0xF8); + dst[A] = (int8u)(rgb >> 15); + src += 2; + dst += 4; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb555_rgba32<1,2,3,0> color_conv_rgb555_to_argb32; //----color_conv_rgb555_to_argb32 + typedef color_conv_rgb555_rgba32<3,2,1,0> color_conv_rgb555_to_abgr32; //----color_conv_rgb555_to_abgr32 + typedef color_conv_rgb555_rgba32<2,1,0,3> color_conv_rgb555_to_bgra32; //----color_conv_rgb555_to_bgra32 + typedef color_conv_rgb555_rgba32<0,1,2,3> color_conv_rgb555_to_rgba32; //----color_conv_rgb555_to_rgba32 + + + //------------------------------------------------color_conv_rgba32_rgb555 + template<int R, int G, int B, int A> class color_conv_rgba32_rgb555 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *(int16u*)dst = (int16u)(((unsigned(src[R]) << 7) & 0x7C00) | + ((unsigned(src[G]) << 2) & 0x3E0) | + ((unsigned(src[B]) >> 3)) | + ((unsigned(src[A]) << 8) & 0x8000)); + src += 4; + dst += 2; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgba32_rgb555<1,2,3,0> color_conv_argb32_to_rgb555; //----color_conv_argb32_to_rgb555 + typedef color_conv_rgba32_rgb555<3,2,1,0> color_conv_abgr32_to_rgb555; //----color_conv_abgr32_to_rgb555 + typedef color_conv_rgba32_rgb555<2,1,0,3> color_conv_bgra32_to_rgb555; //----color_conv_bgra32_to_rgb555 + typedef color_conv_rgba32_rgb555<0,1,2,3> color_conv_rgba32_to_rgb555; //----color_conv_rgba32_to_rgb555 + + + + //------------------------------------------------color_conv_rgb565_rgba32 + template<int R, int G, int B, int A> class color_conv_rgb565_rgba32 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int rgb = *(int16*)src; + dst[R] = (rgb >> 8) & 0xF8; + dst[G] = (rgb >> 3) & 0xFC; + dst[B] = (rgb << 3) & 0xF8; + dst[A] = 255; + src += 2; + dst += 4; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb565_rgba32<1,2,3,0> color_conv_rgb565_to_argb32; //----color_conv_rgb565_to_argb32 + typedef color_conv_rgb565_rgba32<3,2,1,0> color_conv_rgb565_to_abgr32; //----color_conv_rgb565_to_abgr32 + typedef color_conv_rgb565_rgba32<2,1,0,3> color_conv_rgb565_to_bgra32; //----color_conv_rgb565_to_bgra32 + typedef color_conv_rgb565_rgba32<0,1,2,3> color_conv_rgb565_to_rgba32; //----color_conv_rgb565_to_rgba32 + + + //------------------------------------------------color_conv_rgba32_rgb565 + template<int R, int G, int B> class color_conv_rgba32_rgb565 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *(int16u*)dst = (int16u)(((unsigned(src[R]) << 8) & 0xF800) | + ((unsigned(src[G]) << 3) & 0x7E0) | + ((unsigned(src[B]) >> 3))); + src += 4; + dst += 2; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgba32_rgb565<1,2,3> color_conv_argb32_to_rgb565; //----color_conv_argb32_to_rgb565 + typedef color_conv_rgba32_rgb565<3,2,1> color_conv_abgr32_to_rgb565; //----color_conv_abgr32_to_rgb565 + typedef color_conv_rgba32_rgb565<2,1,0> color_conv_bgra32_to_rgb565; //----color_conv_bgra32_to_rgb565 + typedef color_conv_rgba32_rgb565<0,1,2> color_conv_rgba32_to_rgb565; //----color_conv_rgba32_to_rgb565 + + + //---------------------------------------------color_conv_rgb555_to_rgb565 + class color_conv_rgb555_to_rgb565 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + unsigned rgb = *(int16u*)src; + *(int16u*)dst = (int16u)(((rgb << 1) & 0xFFC0) | (rgb & 0x1F)); + src += 2; + dst += 2; + } + while(--width); + } + }; + + + //----------------------------------------------color_conv_rgb565_to_rgb555 + class color_conv_rgb565_to_rgb555 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + unsigned rgb = *(int16u*)src; + *(int16u*)dst = (int16u)(((rgb >> 1) & 0x7FE0) | (rgb & 0x1F)); + src += 2; + dst += 2; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_same<2> color_conv_rgb555_to_rgb555; //----color_conv_rgb555_to_rgb555 + typedef color_conv_same<2> color_conv_rgb565_to_rgb565; //----color_conv_rgb565_to_rgb565 + + + template<int R, int B> class color_conv_rgb24_gray8 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *dst++ = (src[R]*77 + src[1]*150 + src[B]*29) >> 8; + src += 3; + } + while(--width); + } + }; + + typedef color_conv_rgb24_gray8<0,2> color_conv_rgb24_to_gray8; //----color_conv_rgb24_to_gray8 + typedef color_conv_rgb24_gray8<2,0> color_conv_bgr24_to_gray8; //----color_conv_bgr24_to_gray8 + + +} + + + +#endif diff --git a/install b/install new file mode 100644 index 0000000..43126f0 --- /dev/null +++ b/install @@ -0,0 +1,38 @@ +Anti-Grain Geometry is a C++ library distributed in sources +and does not require any installation procedure. The source code +is platform independent and does not have any dependencies on +system APIs (except for very standard C runtime library). +You just take source files and include them into +your project. The sources are maintained to be highly compatible +with most popular C++ compilers, including poor ones, like +Microsoft Visual C++ V6.0. + +On Unix/Linux/MacOS/BeOS/AmigaOS systems you can type "make" to +build src/libagg.a There must be GNU Make utility installed. +Makefiles are very simple, so that if something goes wrong +you could easily fix it. There are no "include files" +dependency suppoeted. +Also note that there's no "make install" option either; +basically the original Makefiles are needed only to build +the examples. + +After building the library you do "cd examples/<YourOS>" and build +the examples in a similar way. + +On most Linux platforms the "automake" environment should work. +It's generously provided by Nikolas Zimmermann, aka WildFox, +who is a key developer of KDE and KSVG. +This process will replace the original Makefiles. + +On Windows there's no library or a DLL created at all. You just +add source files into your project or create a preoject to build +a LIB/DLL if you wish. The problem is that it's very tedious to +maintain building environments for all possible configurations. +I'm sorry for not automating it, but the compensation is that +AGG compiles fine without any hidden problems, nor the neccesity +to configure. +All examples have building environments for Microsoft Visual C++ 6.0 +(.dsp/.dsw) and they are self-sufficient. The newer versions +of the studio can easily convert the projects. + +Also, see "readme" for more details. \ No newline at end of file diff --git a/libagg.m4 b/libagg.m4 new file mode 100644 index 0000000..d09893d --- /dev/null +++ b/libagg.m4 @@ -0,0 +1,34 @@ +# Configure paths for libagg +# Kirill Smelkov 2005-10-23, based on freetype2.m4 by Marcelo Magallon + +# AC_CHECK_LIBAGG([MINIMUM-VERSION [, ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]]) +# Test for libagg, and define LIBAGG_CFLAGS and LIBAGG_LIBS +# +AC_DEFUN([AC_CHECK_LIBAGG], +[ + # Get the cflags and libraries from pkg-config libagg ... + AC_ARG_WITH([libagg], + AS_HELP_STRING([--with-libagg=PREFIX], + [Prefix where libagg is installed (optional)]), + [libagg_prefix="$withval"], + [libagg_prefix=""]) + + libagg_name=libagg + if test "x$libagg_prefix" != "x"; then + libagg_name="$libagg_prefix/lib/pkgconfig/libagg.pc" + fi + + PKG_CHECK_MODULES([LIBAGG], "$libagg_name", success=yes, success=no) + + if test "x$success" = xyes; then + ifelse([$2], , :, [$2]) + + AC_SUBST([LIBAGG_CFLAGS]) + AC_SUBST([LIBAGG_LIBS]) + else + ifelse([$3], , :, [$3]) + fi +]) + +# end of libagg.m4 + diff --git a/libagg.pc.in b/libagg.pc.in new file mode 100644 index 0000000..5d465e3 --- /dev/null +++ b/libagg.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@/agg2 + +Name: libagg +Description: Anti Grain Geometry - A High Quality Rendering Engine for C++ +Version: @VERSION@ +Libs: -L${libdir} -Wl,-rpath,${exec_prefix}/lib -lagg +Cflags: -I${includedir} diff --git a/myapp/CMakeLists.txt b/myapp/CMakeLists.txt new file mode 100644 index 0000000..b0d8fc4 --- /dev/null +++ b/myapp/CMakeLists.txt @@ -0,0 +1,85 @@ +PROJECT( MyAggApp ) + +#modify this!! +SET( AGG_DIR ${antigrain_BINARY_DIR} ) + +# additional are modified Find routines +SET ( CMAKE_MODULE_PATH "${MyAggApp_BINARY_DIR}" ) + +CMAKE_MINIMUM_REQUIRED( VERSION 2.4.8 ) + +# 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 ) + INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/font_freetype ) +ENDIF(WIN32) + +IF(UNIX) + ADD_DEFINITIONS( -D__UNIX__ ) + SET( WIN32GUI "" ) + INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/font_freetype ) + + FIND_PACKAGE(X11) + IF(X11_FOUND) + INCLUDE_DIRECTORIES(${X11_INCLUDE_DIRS}) + LINK_LIBRARIES(${X11_LIBRARIES}) + ENDIF(X11_FOUND) + +ENDIF(UNIX) + +################################################## +# Set all includes, flags, libraries, related to Agg +################################################## + +FIND_PACKAGE( Agg ) +IF( AGG_FOUND ) + #normally the next is needed, but since this very file is in Agg its source, all is already in place + #INCLUDE(${AGG_USE_FILE}) +ELSE( AGG_FOUND ) + MESSAGE( "AGG library was not found" ) +ENDIF( AGG_FOUND ) + +################################################## +# 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 ) + +ADD_EXECUTABLE( my_demo ${WIN32GUI} + my_demo.cpp +) + +IF( agg_USE_AGG2D ) + ADD_EXECUTABLE( agg2d_demo ${WIN32GUI} + agg2d_demo.cpp + ) +ENDIF( agg_USE_AGG2D ) + + diff --git a/myapp/CMakeLists.txt.in b/myapp/CMakeLists.txt.in new file mode 100644 index 0000000..202c883 --- /dev/null +++ b/myapp/CMakeLists.txt.in @@ -0,0 +1,85 @@ +PROJECT( MyAggApp ) + +# additional are modified Find routines +SET ( CMAKE_MODULE_PATH "${MyAggApp_SOURCE_DIR}" ) + +CMAKE_MINIMUM_REQUIRED( VERSION 2.4.8 ) + +IF( COMMAND cmake_policy ) + cmake_policy( SET CMP0003 NEW ) +ENDIF( COMMAND cmake_policy ) + +# 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_BINARY_DIR@/font_win32_tt ) + INCLUDE_DIRECTORIES( @antigrain_BINARY_DIR@/font_freetype ) +ENDIF(WIN32) + +IF(UNIX) + ADD_DEFINITIONS( -D__UNIX__ ) + SET( WIN32GUI "" ) + INCLUDE_DIRECTORIES( @antigrain_BINARY_DIR@/font_freetype ) + + FIND_PACKAGE(X11) + IF(X11_FOUND) + INCLUDE_DIRECTORIES(${X11_INCLUDE_DIRS}) + LINK_LIBRARIES(${X11_LIBRARIES}) + ENDIF(X11_FOUND) + +ENDIF(UNIX) + +################################################## +# Set all includes, flags, libraries, related to Agg +################################################## + +FIND_PACKAGE( Agg ) +IF( AGG_FOUND ) + INCLUDE(${AGG_USE_FILE}) +ELSE( AGG_FOUND ) + MESSAGE( "AGG library was not found" ) +ENDIF( AGG_FOUND ) + +################################################## +# 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 ) + +ADD_EXECUTABLE( my_demo ${WIN32GUI} + my_demo.cpp +) + +IF( agg_USE_AGG2D ) + ADD_EXECUTABLE( agg2_demo ${WIN32GUI} + agg2d_demo.cpp + ) +ENDIF( agg_USE_AGG2D ) + + diff --git a/myapp/agg2d_demo.cpp b/myapp/agg2d_demo.cpp new file mode 100644 index 0000000..dab2547 --- /dev/null +++ b/myapp/agg2d_demo.cpp @@ -0,0 +1,403 @@ +#include <stdio.h> +#include "platform/agg_platform_support.h" +#include "agg2d.h" + +#define pix_format agg::pix_format_bgra32 + +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); + + m_graphics.antiAliasGamma(1.4); + + // 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 + m_graphics.font("Times New Roman", 14.0, false, false); + 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 + m_graphics.font("Times New Roman", 50.0, false, false, Agg2D::VectorFontCache); + 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); + m_graphics.font("Times New Roman", 40.0, false, false, Agg2D::VectorFontCache); + + 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) + //======================================= + m_graphics.font("Verdana", 20.0, false, false, Agg2D::VectorFontCache); + 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::BlendContrast); + 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[]) +{ + the_application app(pix_format, flip_y); + 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 another directory if available.", + 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; +} + + + + + + diff --git a/myapp/my_demo.cpp b/myapp/my_demo.cpp new file mode 100644 index 0000000..8191df1 --- /dev/null +++ b/myapp/my_demo.cpp @@ -0,0 +1,305 @@ +#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" + + +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(rgba8 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, + rgba8(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; + rgba8 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<agg::rgba8> m_slider1; + agg::slider_ctrl<agg::rgba8> m_slider2; + +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_slider2(80, 10+20, 600-10, 19+20, !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); + add_ctrl(m_slider2); + + m_slider1.range(8.0, 100.0); + m_slider1.num_steps(23); + m_slider1.value(32.0); + + m_slider2.range(0.1, 3.0); + m_slider2.value(1.0); + + m_slider1.label("Pixel size=%1.0f"); + m_slider2.label("Gamma=%4.3f"); + + m_slider1.no_transform(); + m_slider2.no_transform(); + } + + + virtual ~the_application() + { + } + + + virtual void on_init() + { + } + + + virtual void on_draw() + { + typedef agg::renderer_base<agg::pixfmt_bgr24> ren_base; + + agg::pixfmt_bgr24 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()); + + ras.gamma(agg::gamma_power(m_slider2.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::rgba8(0,0,0, 255)); + agg::render_scanlines(ras, sl, ren_en); + + + agg::render_scanlines_aa_solid(ras, sl, ren, agg::rgba8(0,0,0)); + + ras.gamma(agg::gamma_none()); + + 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::rgba8(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::rgba8(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::rgba8(0,150,160, 200)); + + // Render the controls + agg::render_ctrl(ras, sl, ren, m_slider1); + agg::render_ctrl(ras, sl, ren, m_slider2); + } + + + + + 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(agg::pix_format_bgr24, flip_y); + app.caption("AGG Example. Anti-Aliasing Demo"); + + if(app.init(600, 400, agg::window_resize)) + { + return app.run(); + } + return 1; +} + + diff --git a/myapp/myproject.cmake b/myapp/myproject.cmake new file mode 100644 index 0000000..b53f895 --- /dev/null +++ b/myapp/myproject.cmake @@ -0,0 +1,28 @@ +# \file myproject.cmake +# \author Klaas Holwerda +# +# Copyright: 2008 (c) Klaas Holwerda +# + +CONFIGURE_FILE(${antigrain_SOURCE_DIR}/bin/FindAgg.cmake + ${antigrain_BINARY_DIR}/myapp/FindAgg.cmake + @ONLY ) + +CONFIGURE_FILE(${antigrain_SOURCE_DIR}/bin/FindEXPAT.cmake +${antigrain_BINARY_DIR}/myapp/FindExpat.cmake +@ONLY ) + +CONFIGURE_FILE(${antigrain_SOURCE_DIR}/bin/FindFreetype.cmake + ${antigrain_BINARY_DIR}/myapp/FindFreetype.cmake + @ONLY ) + +CONFIGURE_FILE(${antigrain_SOURCE_DIR}/myapp/CMakeLists.txt.in + ${antigrain_BINARY_DIR}/myapp/CMakeLists.txt + @ONLY ) +CONFIGURE_FILE(${antigrain_SOURCE_DIR}/myapp/my_demo.cpp + ${antigrain_BINARY_DIR}/myapp/my_demo.cpp + @ONLY ) +CONFIGURE_FILE(${antigrain_SOURCE_DIR}/myapp/agg2d_demo.cpp + ${antigrain_BINARY_DIR}/myapp/agg2d_demo.cpp + @ONLY ) + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..f00c691 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,279 @@ + +SET( antigrain_HEADERS + ${antigrain_SOURCE_DIR}/include/agg_alpha_mask_u8.h + ${antigrain_SOURCE_DIR}/include/agg_arc.h + ${antigrain_SOURCE_DIR}/include/agg_array.h + ${antigrain_SOURCE_DIR}/include/agg_arrowhead.h + ${antigrain_SOURCE_DIR}/include/agg_basics.h + ${antigrain_SOURCE_DIR}/include/agg_bezier_arc.h + ${antigrain_SOURCE_DIR}/include/agg_bitset_iterator.h + ${antigrain_SOURCE_DIR}/include/agg_blur.h + ${antigrain_SOURCE_DIR}/include/agg_bounding_rect.h + ${antigrain_SOURCE_DIR}/include/agg_bspline.h + ${antigrain_SOURCE_DIR}/include/agg_clip_liang_barsky.h + ${antigrain_SOURCE_DIR}/include/agg_color_gray.h + ${antigrain_SOURCE_DIR}/include/agg_color_rgba.h + ${antigrain_SOURCE_DIR}/include/agg_config.h + ${antigrain_SOURCE_DIR}/include/agg_conv_adaptor_vcgen.h + ${antigrain_SOURCE_DIR}/include/agg_conv_adaptor_vpgen.h + ${antigrain_SOURCE_DIR}/include/agg_conv_bspline.h + ${antigrain_SOURCE_DIR}/include/agg_conv_clip_polygon.h + ${antigrain_SOURCE_DIR}/include/agg_conv_clip_polyline.h + ${antigrain_SOURCE_DIR}/include/agg_conv_close_polygon.h + ${antigrain_SOURCE_DIR}/include/agg_conv_concat.h + ${antigrain_SOURCE_DIR}/include/agg_conv_contour.h + ${antigrain_SOURCE_DIR}/include/agg_conv_curve.h + ${antigrain_SOURCE_DIR}/include/agg_conv_dash.h + ${antigrain_SOURCE_DIR}/include/agg_conv_gpc.h + ${antigrain_SOURCE_DIR}/include/agg_conv_marker.h + ${antigrain_SOURCE_DIR}/include/agg_conv_marker_adaptor.h + ${antigrain_SOURCE_DIR}/include/agg_conv_segmentator.h + ${antigrain_SOURCE_DIR}/include/agg_conv_shorten_path.h + ${antigrain_SOURCE_DIR}/include/agg_conv_smooth_poly1.h + ${antigrain_SOURCE_DIR}/include/agg_conv_stroke.h + ${antigrain_SOURCE_DIR}/include/agg_conv_transform.h + ${antigrain_SOURCE_DIR}/include/agg_conv_unclose_polygon.h + ${antigrain_SOURCE_DIR}/include/agg_curves.h + ${antigrain_SOURCE_DIR}/include/agg_dda_line.h + ${antigrain_SOURCE_DIR}/include/agg_ellipse.h + ${antigrain_SOURCE_DIR}/include/agg_ellipse_bresenham.h + ${antigrain_SOURCE_DIR}/include/agg_embedded_raster_fonts.h + ${antigrain_SOURCE_DIR}/include/agg_font_cache_manager.h + ${antigrain_SOURCE_DIR}/include/agg_gamma_functions.h + ${antigrain_SOURCE_DIR}/include/agg_gamma_lut.h + ${antigrain_SOURCE_DIR}/include/agg_glyph_raster_bin.h + ${antigrain_SOURCE_DIR}/include/agg_gradient_lut.h + ${antigrain_SOURCE_DIR}/include/agg_gsv_text.h + ${antigrain_SOURCE_DIR}/include/agg_image_accessors.h + ${antigrain_SOURCE_DIR}/include/agg_image_filters.h + ${antigrain_SOURCE_DIR}/include/agg_line_aa_basics.h + ${antigrain_SOURCE_DIR}/include/agg_math.h + ${antigrain_SOURCE_DIR}/include/agg_math_stroke.h + ${antigrain_SOURCE_DIR}/include/agg_path_length.h + ${antigrain_SOURCE_DIR}/include/agg_path_storage.h + ${antigrain_SOURCE_DIR}/include/agg_path_storage_integer.h + ${antigrain_SOURCE_DIR}/include/agg_pattern_filters_rgba.h + ${antigrain_SOURCE_DIR}/include/agg_pixfmt_amask_adaptor.h + ${antigrain_SOURCE_DIR}/include/agg_pixfmt_gray.h + ${antigrain_SOURCE_DIR}/include/agg_pixfmt_rgb.h + ${antigrain_SOURCE_DIR}/include/agg_pixfmt_rgb_packed.h + ${antigrain_SOURCE_DIR}/include/agg_pixfmt_rgba.h + ${antigrain_SOURCE_DIR}/include/agg_pixfmt_transposer.h + ${antigrain_SOURCE_DIR}/include/agg_rasterizer_cells_aa.h + ${antigrain_SOURCE_DIR}/include/agg_rasterizer_compound_aa.h + ${antigrain_SOURCE_DIR}/include/agg_rasterizer_outline.h + ${antigrain_SOURCE_DIR}/include/agg_rasterizer_outline_aa.h + ${antigrain_SOURCE_DIR}/include/agg_rasterizer_scanline_aa.h + ${antigrain_SOURCE_DIR}/include/agg_rasterizer_sl_clip.h + ${antigrain_SOURCE_DIR}/include/agg_renderer_base.h + ${antigrain_SOURCE_DIR}/include/agg_renderer_markers.h + ${antigrain_SOURCE_DIR}/include/agg_renderer_mclip.h + ${antigrain_SOURCE_DIR}/include/agg_renderer_outline_aa.h + ${antigrain_SOURCE_DIR}/include/agg_renderer_outline_image.h + ${antigrain_SOURCE_DIR}/include/agg_renderer_primitives.h + ${antigrain_SOURCE_DIR}/include/agg_renderer_raster_text.h + ${antigrain_SOURCE_DIR}/include/agg_renderer_scanline.h + ${antigrain_SOURCE_DIR}/include/agg_rendering_buffer.h + ${antigrain_SOURCE_DIR}/include/agg_rendering_buffer_dynarow.h + ${antigrain_SOURCE_DIR}/include/agg_rounded_rect.h + ${antigrain_SOURCE_DIR}/include/agg_scanline_bin.h + ${antigrain_SOURCE_DIR}/include/agg_scanline_boolean_algebra.h + ${antigrain_SOURCE_DIR}/include/agg_scanline_p.h + ${antigrain_SOURCE_DIR}/include/agg_scanline_storage_aa.h + ${antigrain_SOURCE_DIR}/include/agg_scanline_storage_bin.h + ${antigrain_SOURCE_DIR}/include/agg_scanline_u.h + ${antigrain_SOURCE_DIR}/include/agg_shorten_path.h + ${antigrain_SOURCE_DIR}/include/agg_simul_eq.h + ${antigrain_SOURCE_DIR}/include/agg_span_allocator.h + ${antigrain_SOURCE_DIR}/include/agg_span_converter.h + ${antigrain_SOURCE_DIR}/include/agg_span_gouraud.h + ${antigrain_SOURCE_DIR}/include/agg_span_gouraud_gray.h + ${antigrain_SOURCE_DIR}/include/agg_span_gouraud_rgba.h + ${antigrain_SOURCE_DIR}/include/agg_span_gradient.h + ${antigrain_SOURCE_DIR}/include/agg_span_gradient_alpha.h + ${antigrain_SOURCE_DIR}/include/agg_span_image_filter.h + ${antigrain_SOURCE_DIR}/include/agg_span_image_filter_gray.h + ${antigrain_SOURCE_DIR}/include/agg_span_image_filter_rgb.h + ${antigrain_SOURCE_DIR}/include/agg_span_image_filter_rgba.h + ${antigrain_SOURCE_DIR}/include/agg_span_interpolator_adaptor.h + ${antigrain_SOURCE_DIR}/include/agg_span_interpolator_linear.h + ${antigrain_SOURCE_DIR}/include/agg_span_interpolator_persp.h + ${antigrain_SOURCE_DIR}/include/agg_span_interpolator_trans.h + ${antigrain_SOURCE_DIR}/include/agg_span_pattern_gray.h + ${antigrain_SOURCE_DIR}/include/agg_span_pattern_rgb.h + ${antigrain_SOURCE_DIR}/include/agg_span_pattern_rgba.h + ${antigrain_SOURCE_DIR}/include/agg_span_solid.h + ${antigrain_SOURCE_DIR}/include/agg_span_subdiv_adaptor.h + ${antigrain_SOURCE_DIR}/include/agg_trans_affine.h + ${antigrain_SOURCE_DIR}/include/agg_trans_bilinear.h + ${antigrain_SOURCE_DIR}/include/agg_trans_double_path.h + ${antigrain_SOURCE_DIR}/include/agg_trans_perspective.h + ${antigrain_SOURCE_DIR}/include/agg_trans_single_path.h + ${antigrain_SOURCE_DIR}/include/agg_trans_viewport.h + ${antigrain_SOURCE_DIR}/include/agg_trans_warp_magnifier.h + ${antigrain_SOURCE_DIR}/include/agg_vcgen_bspline.h + ${antigrain_SOURCE_DIR}/include/agg_vcgen_contour.h + ${antigrain_SOURCE_DIR}/include/agg_vcgen_dash.h + ${antigrain_SOURCE_DIR}/include/agg_vcgen_markers_term.h + ${antigrain_SOURCE_DIR}/include/agg_vcgen_smooth_poly1.h + ${antigrain_SOURCE_DIR}/include/agg_vcgen_stroke.h + ${antigrain_SOURCE_DIR}/include/agg_vcgen_vertex_sequence.h + ${antigrain_SOURCE_DIR}/include/agg_vertex_sequence.h + ${antigrain_SOURCE_DIR}/include/agg_vpgen_clip_polygon.h + ${antigrain_SOURCE_DIR}/include/agg_vpgen_clip_polyline.h + ${antigrain_SOURCE_DIR}/include/agg_vpgen_segmentator.h + + ${antigrain_SOURCE_DIR}/include/agg_span_gradient_contour.h + ${antigrain_SOURCE_DIR}/include/agg_span_gradient_image.h +) + +ADD_LIBRARY( antigrain + + agg_arc.cpp + agg_arrowhead.cpp + agg_bezier_arc.cpp + agg_bspline.cpp + agg_curves.cpp + agg_embedded_raster_fonts.cpp + agg_gsv_text.cpp + agg_image_filters.cpp + agg_line_aa_basics.cpp + agg_line_profile_aa.cpp + agg_rounded_rect.cpp + agg_sqrt_tables.cpp + agg_trans_affine.cpp + agg_trans_double_path.cpp + agg_trans_single_path.cpp + agg_trans_warp_magnifier.cpp + agg_vcgen_bspline.cpp + agg_vcgen_contour.cpp + agg_vcgen_dash.cpp + agg_vcgen_markers_term.cpp + agg_vcgen_smooth_poly1.cpp + agg_vcgen_stroke.cpp + agg_vpgen_clip_polygon.cpp + agg_vpgen_segmentator.cpp + + ${antigrain_HEADERS} +) + +#controls code for interactive modifying samples +SET( controls_HEADERS + ${antigrain_SOURCE_DIR}/include/ctrl/agg_slider_ctrl.h + ${antigrain_SOURCE_DIR}/include/ctrl/agg_spline_ctrl.h + ${antigrain_SOURCE_DIR}/include/ctrl/agg_scale_ctrl.h + ${antigrain_SOURCE_DIR}/include/ctrl/agg_rbox_ctrl.h + ${antigrain_SOURCE_DIR}/include/ctrl/agg_polygon_ctrl.h + ${antigrain_SOURCE_DIR}/include/ctrl/agg_gamma_spline.h + ${antigrain_SOURCE_DIR}/include/ctrl/agg_gamma_ctrl.h + ${antigrain_SOURCE_DIR}/include/ctrl/agg_ctrl.h + ${antigrain_SOURCE_DIR}/include/ctrl/agg_cbox_ctrl.h + ${antigrain_SOURCE_DIR}/include/ctrl/agg_bezier_ctrl.h +) + +ADD_LIBRARY( controls + ctrl/agg_spline_ctrl.cpp + ctrl/agg_slider_ctrl.cpp + ctrl/agg_scale_ctrl.cpp + ctrl/agg_rbox_ctrl.cpp + ctrl/agg_polygon_ctrl.cpp + ctrl/agg_gamma_spline.cpp + ctrl/agg_gamma_ctrl.cpp + ctrl/agg_cbox_ctrl.cpp + ctrl/agg_bezier_ctrl.cpp + + ${controls_HEADERS} +) + +#freetype library + +IF ( agg_USE_FREETYPE ) + + INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/font_freetype ) + + ADD_LIBRARY( freetypefont + ../font_freetype/agg_font_freetype.h + ../font_freetype/agg_font_freetype.cpp + ) + SET_TARGET_PROPERTIES( freetypefont PROPERTIES OUTPUT_NAME aggfontfreetype${PFDEBUG} ) + INSTALL( TARGETS freetypefont DESTINATION lib ) + INSTALL( FILES ../font_freetype/agg_font_freetype.h DESTINATION agg/font_freetype ) +ENDIF ( agg_USE_FREETYPE ) + +#platform stuff to ease sample use +SET( platform_HEADERS + ${antigrain_SOURCE_DIR}/include/platform/agg_platform_support.h +) + +IF(WIN32) + INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/font_win32_tt ) + + ADD_LIBRARY( platform + ../src/platform/win32/agg_win32_bmp.cpp + ../src/platform/win32/agg_platform_support.cpp + ../font_win32_tt/agg_font_win32_tt.cpp + + ${platform_HEADERS} + ) + INSTALL( FILES ../font_win32_tt/agg_font_win32_tt.h DESTINATION agg/font_win32_tt ) +ENDIF(WIN32) +IF(UNIX) + ADD_LIBRARY( platform + ../src/platform/X11/agg_platform_support.cpp + + ${platform_HEADERS} + ) +ENDIF(UNIX) +IF(APPLE) + ADD_LIBRARY( platform + ../src/platform/mac/agg_mac_pmap.cpp + ../src/platform/mac/agg_platform_support.cpp + + ${platform_HEADERS} + ) +ENDIF(APPLE) + +IF( SDL_FOUND AND agg_USE_SDL_PLATFORM ) + ADD_LIBRARY( sdlplatform + ../src/platform/sdl/agg_platform_support.cpp + + ${platform_HEADERS} + ) + INSTALL( TARGETS sdlplatform DESTINATION lib ) + SET_TARGET_PROPERTIES( sdlplatform PROPERTIES OUTPUT_NAME aggsdlplatform${PFDEBUG} ) +ENDIF( SDL_FOUND AND agg_USE_SDL_PLATFORM ) + +# boolean operations library GPC + +IF ( agg_USE_GPC ) + INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/gpc ) + + ADD_LIBRARY( gpcbool + ../gpc/gpc.c + ../gpc/gpc.h + ) + INSTALL( TARGETS gpcbool DESTINATION lib ) + INSTALL( FILES ../gpc/gpc.h DESTINATION agg/gpc ) + SET_TARGET_PROPERTIES( gpcbool PROPERTIES OUTPUT_NAME gpc${PFDEBUG} ) +ENDIF ( agg_USE_GPC ) + +IF ( agg_USE_AGG2D ) + INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/agg2d ) + + ADD_LIBRARY( agg2d + ../agg2d/agg2d.cpp + ../agg2d/agg2d.h + ) + INSTALL( TARGETS agg2d DESTINATION lib ) + INSTALL( FILES ../agg2d/agg2d.h DESTINATION agg/agg2d ) + SET_TARGET_PROPERTIES( agg2d PROPERTIES OUTPUT_NAME agg2d${PFDEBUG} ) +ENDIF ( agg_USE_AGG2D ) + +SET_TARGET_PROPERTIES( antigrain PROPERTIES OUTPUT_NAME agg${PFDEBUG} ) +SET_TARGET_PROPERTIES( controls PROPERTIES OUTPUT_NAME aggctrl${PFDEBUG} ) +SET_TARGET_PROPERTIES( platform PROPERTIES OUTPUT_NAME aggplatform${PFDEBUG} ) + +INSTALL( FILES ${antigrain_HEADERS} DESTINATION agg/include ) +INSTALL( FILES ${controls_HEADERS} DESTINATION agg/include/ctrl ) +INSTALL( FILES ${platform_HEADERS} DESTINATION agg/include/platform ) +INSTALL( TARGETS antigrain controls platform DESTINATION lib ) diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..ff81b93 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,60 @@ +include ../Makefile.in.$(shell uname) + +CXXFLAGS= $(AGGCXXFLAGS) -I../include -L./ + +SRC_CXX=\ +agg_arc.cpp \ +agg_arrowhead.cpp \ +agg_bezier_arc.cpp \ +agg_bspline.cpp \ +agg_color_rgba.cpp \ +agg_curves.cpp \ +agg_vcgen_contour.cpp \ +agg_vcgen_dash.cpp \ +agg_vcgen_markers_term.cpp \ +agg_vcgen_smooth_poly1.cpp \ +agg_vcgen_stroke.cpp \ +agg_vcgen_bspline.cpp \ +agg_gsv_text.cpp \ +agg_image_filters.cpp \ +agg_line_aa_basics.cpp \ +agg_line_profile_aa.cpp \ +agg_rounded_rect.cpp \ +agg_sqrt_tables.cpp \ +agg_embedded_raster_fonts.cpp \ +agg_trans_affine.cpp \ +agg_trans_warp_magnifier.cpp \ +agg_trans_single_path.cpp \ +agg_trans_double_path.cpp \ +agg_vpgen_clip_polygon.cpp \ +agg_vpgen_clip_polyline.cpp \ +agg_vpgen_segmentator.cpp \ +ctrl/agg_cbox_ctrl.cpp \ +ctrl/agg_gamma_ctrl.cpp \ +ctrl/agg_gamma_spline.cpp \ +ctrl/agg_rbox_ctrl.cpp \ +ctrl/agg_slider_ctrl.cpp \ +ctrl/agg_spline_ctrl.cpp \ +ctrl/agg_scale_ctrl.cpp \ +ctrl/agg_polygon_ctrl.cpp \ +ctrl/agg_bezier_ctrl.cpp + +SRC_C=\ +../gpc/gpc.c + + +OBJ=$(SRC_CXX:.cpp=.o) $(SRC_C:.c=.o) + +all: $(OBJ) + $(LIB) libagg.a $(OBJ) + +clean: + rm -f *.o *.a ctrl/*.o ../gpc/*.o + rm -rf SunWS_cache + rm -rf ctrl/SunWS_cache + +%.o: %.cpp + $(CXX) -c $(CXXFLAGS) $*.cpp -o $@ + +%.o: %.c + $(C) -c $(CXXFLAGS) $*.c -o $@ diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..f7df04e --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,48 @@ +SUBDIRS = ctrl . platform + +INCLUDES = -I$(top_srcdir)/include + +lib_LTLIBRARIES = libagg.la + +libagg_la_LDFLAGS = -no-undefined -version-info @AGG_LIB_VERSION@ +libagg_la_SOURCES = agg_arc.cpp \ + agg_arrowhead.cpp \ + agg_bezier_arc.cpp \ + agg_bspline.cpp \ + agg_color_rgba.cpp \ + agg_curves.cpp \ + agg_embedded_raster_fonts.cpp \ + agg_gsv_text.cpp \ + agg_image_filters.cpp \ + agg_line_aa_basics.cpp \ + agg_line_profile_aa.cpp \ + agg_rounded_rect.cpp \ + agg_sqrt_tables.cpp \ + agg_trans_affine.cpp \ + agg_trans_double_path.cpp \ + agg_trans_single_path.cpp \ + agg_trans_warp_magnifier.cpp \ + agg_vcgen_bspline.cpp \ + agg_vcgen_contour.cpp \ + agg_vcgen_dash.cpp \ + agg_vcgen_markers_term.cpp \ + agg_vcgen_smooth_poly1.cpp \ + agg_vcgen_stroke.cpp \ + agg_vpgen_clip_polygon.cpp \ + agg_vpgen_clip_polyline.cpp \ + agg_vpgen_segmentator.cpp + +if ENABLE_GPC +GPCLD=$(top_builddir)/gpc/libagggpc.la +else +GPCLD= +endif + +if ENABLE_CTRL +CTRLLD=$(top_builddir)/src/ctrl/libaggctrl.la +else +CTRLLD= +endif + +libagg_la_LIBADD = $(GPCLD) $(CTRLLD) + diff --git a/src/agg_arc.cpp b/src/agg_arc.cpp new file mode 100644 index 0000000..4262aab --- /dev/null +++ b/src/agg_arc.cpp @@ -0,0 +1,106 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Arc vertex generator +// +//---------------------------------------------------------------------------- + +#include <cmath> +#include "agg_arc.h" + + +namespace agg +{ + //------------------------------------------------------------------------ + arc::arc(double x, double y, + double rx, double ry, + double a1, double a2, + bool ccw) : + m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0) + { + normalize(a1, a2, ccw); + } + + //------------------------------------------------------------------------ + void arc::init(double x, double y, + double rx, double ry, + double a1, double a2, + bool ccw) + { + m_x = x; m_y = y; + m_rx = rx; m_ry = ry; + normalize(a1, a2, ccw); + } + + //------------------------------------------------------------------------ + void arc::approximation_scale(double s) + { + m_scale = s; + if(m_initialized) + { + normalize(m_start, m_end, m_ccw); + } + } + + //------------------------------------------------------------------------ + void arc::rewind(unsigned) + { + m_path_cmd = path_cmd_move_to; + m_angle = m_start; + } + + //------------------------------------------------------------------------ + unsigned arc::vertex(double* x, double* y) + { + if(is_stop(m_path_cmd)) return path_cmd_stop; + if((m_angle < m_end - m_da/4) != m_ccw) + { + *x = m_x + std::cos(m_end) * m_rx; + *y = m_y + std::sin(m_end) * m_ry; + m_path_cmd = path_cmd_stop; + return path_cmd_line_to; + } + + *x = m_x + std::cos(m_angle) * m_rx; + *y = m_y + std::sin(m_angle) * m_ry; + + m_angle += m_da; + + unsigned pf = m_path_cmd; + m_path_cmd = path_cmd_line_to; + return pf; + } + + //------------------------------------------------------------------------ + void arc::normalize(double a1, double a2, bool ccw) + { + double ra = (std::fabs(m_rx) + std::fabs(m_ry)) / 2; + m_da = std::acos(ra / (ra + 0.125 / m_scale)) * 2; + if(ccw) + { + while(a2 < a1) a2 += pi * 2.0; + } + else + { + while(a1 < a2) a1 += pi * 2.0; + m_da = -m_da; + } + m_ccw = ccw; + m_start = a1; + m_end = a2; + m_initialized = true; + } + +} diff --git a/src/agg_arrowhead.cpp b/src/agg_arrowhead.cpp new file mode 100644 index 0000000..1a6f8b4 --- /dev/null +++ b/src/agg_arrowhead.cpp @@ -0,0 +1,110 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Simple arrowhead/arrowtail generator +// +//---------------------------------------------------------------------------- + +#include "agg_arrowhead.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + arrowhead::arrowhead() : + m_head_d1(1.0), + m_head_d2(1.0), + m_head_d3(1.0), + m_head_d4(0.0), + m_tail_d1(1.0), + m_tail_d2(1.0), + m_tail_d3(1.0), + m_tail_d4(0.0), + m_head_flag(false), + m_tail_flag(false), + m_curr_id(0), + m_curr_coord(0) + { + } + + + + //------------------------------------------------------------------------ + void arrowhead::rewind(unsigned path_id) + { + m_curr_id = path_id; + m_curr_coord = 0; + if(path_id == 0) + { + if(!m_tail_flag) + { + m_cmd[0] = path_cmd_stop; + return; + } + m_coord[0] = m_tail_d1; m_coord[1] = 0.0; + m_coord[2] = m_tail_d1 - m_tail_d4; m_coord[3] = m_tail_d3; + m_coord[4] = -m_tail_d2 - m_tail_d4; m_coord[5] = m_tail_d3; + m_coord[6] = -m_tail_d2; m_coord[7] = 0.0; + m_coord[8] = -m_tail_d2 - m_tail_d4; m_coord[9] = -m_tail_d3; + m_coord[10] = m_tail_d1 - m_tail_d4; m_coord[11] = -m_tail_d3; + + m_cmd[0] = path_cmd_move_to; + m_cmd[1] = path_cmd_line_to; + m_cmd[2] = path_cmd_line_to; + m_cmd[3] = path_cmd_line_to; + m_cmd[4] = path_cmd_line_to; + m_cmd[5] = path_cmd_line_to; + m_cmd[7] = path_cmd_end_poly | path_flags_close | path_flags_ccw; + m_cmd[6] = path_cmd_stop; + return; + } + + if(path_id == 1) + { + if(!m_head_flag) + { + m_cmd[0] = path_cmd_stop; + return; + } + m_coord[0] = -m_head_d1; m_coord[1] = 0.0; + m_coord[2] = m_head_d2 + m_head_d4; m_coord[3] = -m_head_d3; + m_coord[4] = m_head_d2; m_coord[5] = 0.0; + m_coord[6] = m_head_d2 + m_head_d4; m_coord[7] = m_head_d3; + + m_cmd[0] = path_cmd_move_to; + m_cmd[1] = path_cmd_line_to; + m_cmd[2] = path_cmd_line_to; + m_cmd[3] = path_cmd_line_to; + m_cmd[4] = path_cmd_end_poly | path_flags_close | path_flags_ccw; + m_cmd[5] = path_cmd_stop; + return; + } + } + + + //------------------------------------------------------------------------ + unsigned arrowhead::vertex(double* x, double* y) + { + if(m_curr_id < 2) + { + unsigned curr_idx = m_curr_coord * 2; + *x = m_coord[curr_idx]; + *y = m_coord[curr_idx + 1]; + return m_cmd[m_curr_coord++]; + } + return path_cmd_stop; + } + +} diff --git a/src/agg_bezier_arc.cpp b/src/agg_bezier_arc.cpp new file mode 100644 index 0000000..4bcd9d8 --- /dev/null +++ b/src/agg_bezier_arc.cpp @@ -0,0 +1,258 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e., +// 4, 7, 10, or 13 vertices. +// +//---------------------------------------------------------------------------- + + +#include <cmath> +#include "agg_bezier_arc.h" + + +namespace agg +{ + + // This epsilon is used to prevent us from adding degenerate curves + // (converging to a single point). + // The value isn't very critical. Function arc_to_bezier() has a limit + // of the sweep_angle. If fabs(sweep_angle) exceeds pi/2 the curve + // becomes inaccurate. But slight exceeding is quite appropriate. + //-------------------------------------------------bezier_arc_angle_epsilon + const double bezier_arc_angle_epsilon = 0.01; + + //------------------------------------------------------------arc_to_bezier + void arc_to_bezier(double cx, double cy, double rx, double ry, + double start_angle, double sweep_angle, + double* curve) + { + double x0 = std::cos(sweep_angle / 2.0); + double y0 = std::sin(sweep_angle / 2.0); + double tx = (1.0 - x0) * 4.0 / 3.0; + double ty = y0 - tx * x0 / y0; + double px[4]; + double py[4]; + px[0] = x0; + py[0] = -y0; + px[1] = x0 + tx; + py[1] = -ty; + px[2] = x0 + tx; + py[2] = ty; + px[3] = x0; + py[3] = y0; + + double sn = std::sin(start_angle + sweep_angle / 2.0); + double cs = std::cos(start_angle + sweep_angle / 2.0); + + unsigned i; + for(i = 0; i < 4; i++) + { + curve[i * 2] = cx + rx * (px[i] * cs - py[i] * sn); + curve[i * 2 + 1] = cy + ry * (px[i] * sn + py[i] * cs); + } + } + + + + //------------------------------------------------------------------------ + void bezier_arc::init(double x, double y, + double rx, double ry, + double start_angle, + double sweep_angle) + { + start_angle = std::fmod(start_angle, 2.0 * pi); + if(sweep_angle >= 2.0 * pi) sweep_angle = 2.0 * pi; + if(sweep_angle <= -2.0 * pi) sweep_angle = -2.0 * pi; + + if(std::fabs(sweep_angle) < 1e-10) + { + m_num_vertices = 4; + m_cmd = path_cmd_line_to; + m_vertices[0] = x + rx * std::cos(start_angle); + m_vertices[1] = y + ry * std::sin(start_angle); + m_vertices[2] = x + rx * std::cos(start_angle + sweep_angle); + m_vertices[3] = y + ry * std::sin(start_angle + sweep_angle); + return; + } + + double total_sweep = 0.0; + double local_sweep = 0.0; + double prev_sweep; + m_num_vertices = 2; + m_cmd = path_cmd_curve4; + bool done = false; + do + { + if(sweep_angle < 0.0) + { + prev_sweep = total_sweep; + local_sweep = -pi * 0.5; + total_sweep -= pi * 0.5; + if(total_sweep <= sweep_angle + bezier_arc_angle_epsilon) + { + local_sweep = sweep_angle - prev_sweep; + done = true; + } + } + else + { + prev_sweep = total_sweep; + local_sweep = pi * 0.5; + total_sweep += pi * 0.5; + if(total_sweep >= sweep_angle - bezier_arc_angle_epsilon) + { + local_sweep = sweep_angle - prev_sweep; + done = true; + } + } + + arc_to_bezier(x, y, rx, ry, + start_angle, + local_sweep, + m_vertices + m_num_vertices - 2); + + m_num_vertices += 6; + start_angle += local_sweep; + } + while(!done && m_num_vertices < 26); + } + + + + + //-------------------------------------------------------------------- + void bezier_arc_svg::init(double x0, double y0, + double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x2, double y2) + { + m_radii_ok = true; + + if(rx < 0.0) rx = -rx; + if(ry < 0.0) ry = -rx; + + // Calculate the middle point between + // the current and the final points + //------------------------ + double dx2 = (x0 - x2) / 2.0; + double dy2 = (y0 - y2) / 2.0; + + double cos_a = std::cos(angle); + double sin_a = std::sin(angle); + + // Calculate (x1, y1) + //------------------------ + double x1 = cos_a * dx2 + sin_a * dy2; + double y1 = -sin_a * dx2 + cos_a * dy2; + + // Ensure radii are large enough + //------------------------ + double prx = rx * rx; + double pry = ry * ry; + double px1 = x1 * x1; + double py1 = y1 * y1; + + // Check that radii are large enough + //------------------------ + double radii_check = px1/prx + py1/pry; + if(radii_check > 1.0) + { + rx = std::sqrt(radii_check) * rx; + ry = std::sqrt(radii_check) * ry; + prx = rx * rx; + pry = ry * ry; + if(radii_check > 10.0) m_radii_ok = false; + } + + // Calculate (cx1, cy1) + //------------------------ + double sign = (large_arc_flag == sweep_flag) ? -1.0 : 1.0; + double sq = (prx*pry - prx*py1 - pry*px1) / (prx*py1 + pry*px1); + double coef = sign * std::sqrt((sq < 0) ? 0 : sq); + double cx1 = coef * ((rx * y1) / ry); + double cy1 = coef * -((ry * x1) / rx); + + // + // Calculate (cx, cy) from (cx1, cy1) + //------------------------ + double sx2 = (x0 + x2) / 2.0; + double sy2 = (y0 + y2) / 2.0; + double cx = sx2 + (cos_a * cx1 - sin_a * cy1); + double cy = sy2 + (sin_a * cx1 + cos_a * cy1); + + // Calculate the start_angle (angle1) and the sweep_angle (dangle) + //------------------------ + double ux = (x1 - cx1) / rx; + double uy = (y1 - cy1) / ry; + double vx = (-x1 - cx1) / rx; + double vy = (-y1 - cy1) / ry; + double p, n; + + // Calculate the angle start + //------------------------ + n = std::sqrt(ux*ux + uy*uy); + p = ux; // (1 * ux) + (0 * uy) + sign = (uy < 0) ? -1.0 : 1.0; + double v = p / n; + if(v < -1.0) v = -1.0; + if(v > 1.0) v = 1.0; + double start_angle = sign * std::acos(v); + + // Calculate the sweep angle + //------------------------ + n = std::sqrt((ux*ux + uy*uy) * (vx*vx + vy*vy)); + p = ux * vx + uy * vy; + sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0; + v = p / n; + if(v < -1.0) v = -1.0; + if(v > 1.0) v = 1.0; + double sweep_angle = sign * std::acos(v); + if(!sweep_flag && sweep_angle > 0) + { + sweep_angle -= pi * 2.0; + } + else + if (sweep_flag && sweep_angle < 0) + { + sweep_angle += pi * 2.0; + } + + // We can now build and transform the resulting arc + //------------------------ + m_arc.init(0.0, 0.0, rx, ry, start_angle, sweep_angle); + trans_affine mtx = trans_affine_rotation(angle); + mtx *= trans_affine_translation(cx, cy); + + for(unsigned i = 2; i < m_arc.num_vertices()-2; i += 2) + { + mtx.transform(m_arc.vertices() + i, m_arc.vertices() + i + 1); + } + + // We must make sure that the starting and ending points + // exactly coincide with the initial (x0,y0) and (x2,y2) + m_arc.vertices()[0] = x0; + m_arc.vertices()[1] = y0; + if(m_arc.num_vertices() > 2) + { + m_arc.vertices()[m_arc.num_vertices() - 2] = x2; + m_arc.vertices()[m_arc.num_vertices() - 1] = y2; + } + } + + +} diff --git a/src/agg_bspline.cpp b/src/agg_bspline.cpp new file mode 100644 index 0000000..e1fda9f --- /dev/null +++ b/src/agg_bspline.cpp @@ -0,0 +1,284 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class bspline +// +//---------------------------------------------------------------------------- + +#include "agg_bspline.h" + +namespace agg +{ + //------------------------------------------------------------------------ + bspline::bspline() : + m_max(0), + m_num(0), + m_x(0), + m_y(0), + m_last_idx(-1) + { + } + + //------------------------------------------------------------------------ + bspline::bspline(int num) : + m_max(0), + m_num(0), + m_x(0), + m_y(0), + m_last_idx(-1) + { + init(num); + } + + //------------------------------------------------------------------------ + bspline::bspline(int num, const double* x, const double* y) : + m_max(0), + m_num(0), + m_x(0), + m_y(0), + m_last_idx(-1) + { + init(num, x, y); + } + + + //------------------------------------------------------------------------ + void bspline::init(int max) + { + if(max > 2 && max > m_max) + { + m_am.resize(max * 3); + m_max = max; + m_x = &m_am[m_max]; + m_y = &m_am[m_max * 2]; + } + m_num = 0; + m_last_idx = -1; + } + + + //------------------------------------------------------------------------ + void bspline::add_point(double x, double y) + { + if(m_num < m_max) + { + m_x[m_num] = x; + m_y[m_num] = y; + ++m_num; + } + } + + + //------------------------------------------------------------------------ + void bspline::prepare() + { + if(m_num > 2) + { + int i, k, n1; + double* temp; + double* r; + double* s; + double h, p, d, f, e; + + for(k = 0; k < m_num; k++) + { + m_am[k] = 0.0; + } + + n1 = 3 * m_num; + + pod_array<double> al(n1); + temp = &al[0]; + + for(k = 0; k < n1; k++) + { + temp[k] = 0.0; + } + + r = temp + m_num; + s = temp + m_num * 2; + + n1 = m_num - 1; + d = m_x[1] - m_x[0]; + e = (m_y[1] - m_y[0]) / d; + + for(k = 1; k < n1; k++) + { + h = d; + d = m_x[k + 1] - m_x[k]; + f = e; + e = (m_y[k + 1] - m_y[k]) / d; + al[k] = d / (d + h); + r[k] = 1.0 - al[k]; + s[k] = 6.0 * (e - f) / (h + d); + } + + for(k = 1; k < n1; k++) + { + p = 1.0 / (r[k] * al[k - 1] + 2.0); + al[k] *= -p; + s[k] = (s[k] - r[k] * s[k - 1]) * p; + } + + m_am[n1] = 0.0; + al[n1 - 1] = s[n1 - 1]; + m_am[n1 - 1] = al[n1 - 1]; + + for(k = n1 - 2, i = 0; i < m_num - 2; i++, k--) + { + al[k] = al[k] * al[k + 1] + s[k]; + m_am[k] = al[k]; + } + } + m_last_idx = -1; + } + + + + //------------------------------------------------------------------------ + void bspline::init(int num, const double* x, const double* y) + { + if(num > 2) + { + init(num); + int i; + for(i = 0; i < num; i++) + { + add_point(*x++, *y++); + } + prepare(); + } + m_last_idx = -1; + } + + + //------------------------------------------------------------------------ + void bspline::bsearch(int n, const double *x, double x0, int *i) + { + int j = n - 1; + int k; + + for(*i = 0; (j - *i) > 1; ) + { + if(x0 < x[k = (*i + j) >> 1]) j = k; + else *i = k; + } + } + + + + //------------------------------------------------------------------------ + double bspline::interpolation(double x, int i) const + { + int j = i + 1; + double d = m_x[i] - m_x[j]; + double h = x - m_x[j]; + double r = m_x[i] - x; + double p = d * d / 6.0; + return (m_am[j] * r * r * r + m_am[i] * h * h * h) / 6.0 / d + + ((m_y[j] - m_am[j] * p) * r + (m_y[i] - m_am[i] * p) * h) / d; + } + + + //------------------------------------------------------------------------ + double bspline::extrapolation_left(double x) const + { + double d = m_x[1] - m_x[0]; + return (-d * m_am[1] / 6 + (m_y[1] - m_y[0]) / d) * + (x - m_x[0]) + + m_y[0]; + } + + //------------------------------------------------------------------------ + double bspline::extrapolation_right(double x) const + { + double d = m_x[m_num - 1] - m_x[m_num - 2]; + return (d * m_am[m_num - 2] / 6 + (m_y[m_num - 1] - m_y[m_num - 2]) / d) * + (x - m_x[m_num - 1]) + + m_y[m_num - 1]; + } + + //------------------------------------------------------------------------ + double bspline::get(double x) const + { + if(m_num > 2) + { + int i; + + // Extrapolation on the left + if(x < m_x[0]) return extrapolation_left(x); + + // Extrapolation on the right + if(x >= m_x[m_num - 1]) return extrapolation_right(x); + + // Interpolation + bsearch(m_num, m_x, x, &i); + return interpolation(x, i); + } + return 0.0; + } + + + //------------------------------------------------------------------------ + double bspline::get_stateful(double x) const + { + if(m_num > 2) + { + // Extrapolation on the left + if(x < m_x[0]) return extrapolation_left(x); + + // Extrapolation on the right + if(x >= m_x[m_num - 1]) return extrapolation_right(x); + + if(m_last_idx >= 0) + { + // Check if x is not in current range + if(x < m_x[m_last_idx] || x > m_x[m_last_idx + 1]) + { + // Check if x between next points (most probably) + if(m_last_idx < m_num - 2 && + x >= m_x[m_last_idx + 1] && + x <= m_x[m_last_idx + 2]) + { + ++m_last_idx; + } + else + if(m_last_idx > 0 && + x >= m_x[m_last_idx - 1] && + x <= m_x[m_last_idx]) + { + // x is between pevious points + --m_last_idx; + } + else + { + // Else perform full search + bsearch(m_num, m_x, x, &m_last_idx); + } + } + return interpolation(x, m_last_idx); + } + else + { + // Interpolation + bsearch(m_num, m_x, x, &m_last_idx); + return interpolation(x, m_last_idx); + } + } + return 0.0; + } + +} + diff --git a/src/agg_color_rgba.cpp b/src/agg_color_rgba.cpp new file mode 100644 index 0000000..9fe1534 --- /dev/null +++ b/src/agg_color_rgba.cpp @@ -0,0 +1,17 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2009 John Horigan (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: john@glyphic.com.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- + +// rgbaN construction from grayN types is no longer required, +// as grayN types now define their own conversions to rgbaN. diff --git a/src/agg_curves.cpp b/src/agg_curves.cpp new file mode 100644 index 0000000..a08fcb9 --- /dev/null +++ b/src/agg_curves.cpp @@ -0,0 +1,613 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include <cmath> +#include "agg_curves.h" +#include "agg_math.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + const double curve_distance_epsilon = 1e-30; + const double curve_collinearity_epsilon = 1e-30; + const double curve_angle_tolerance_epsilon = 0.01; + enum curve_recursion_limit_e { curve_recursion_limit = 32 }; + + + + //------------------------------------------------------------------------ + void curve3_inc::approximation_scale(double s) + { + m_scale = s; + } + + //------------------------------------------------------------------------ + double curve3_inc::approximation_scale() const + { + return m_scale; + } + + //------------------------------------------------------------------------ + void curve3_inc::init(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + m_start_x = x1; + m_start_y = y1; + m_end_x = x3; + m_end_y = y3; + + double dx1 = x2 - x1; + double dy1 = y2 - y1; + double dx2 = x3 - x2; + double dy2 = y3 - y2; + + double len = std::sqrt(dx1 * dx1 + dy1 * dy1) + std::sqrt(dx2 * dx2 + dy2 * dy2); + + m_num_steps = uround(len * 0.25 * m_scale); + + if(m_num_steps < 4) + { + m_num_steps = 4; + } + + double subdivide_step = 1.0 / m_num_steps; + double subdivide_step2 = subdivide_step * subdivide_step; + + double tmpx = (x1 - x2 * 2.0 + x3) * subdivide_step2; + double tmpy = (y1 - y2 * 2.0 + y3) * subdivide_step2; + + m_saved_fx = m_fx = x1; + m_saved_fy = m_fy = y1; + + m_saved_dfx = m_dfx = tmpx + (x2 - x1) * (2.0 * subdivide_step); + m_saved_dfy = m_dfy = tmpy + (y2 - y1) * (2.0 * subdivide_step); + + m_ddfx = tmpx * 2.0; + m_ddfy = tmpy * 2.0; + + m_step = m_num_steps; + } + + //------------------------------------------------------------------------ + void curve3_inc::rewind(unsigned) + { + if(m_num_steps == 0) + { + m_step = -1; + return; + } + m_step = m_num_steps; + m_fx = m_saved_fx; + m_fy = m_saved_fy; + m_dfx = m_saved_dfx; + m_dfy = m_saved_dfy; + } + + //------------------------------------------------------------------------ + unsigned curve3_inc::vertex(double* x, double* y) + { + if(m_step < 0) return path_cmd_stop; + if(m_step == m_num_steps) + { + *x = m_start_x; + *y = m_start_y; + --m_step; + return path_cmd_move_to; + } + if(m_step == 0) + { + *x = m_end_x; + *y = m_end_y; + --m_step; + return path_cmd_line_to; + } + m_fx += m_dfx; + m_fy += m_dfy; + m_dfx += m_ddfx; + m_dfy += m_ddfy; + *x = m_fx; + *y = m_fy; + --m_step; + return path_cmd_line_to; + } + + //------------------------------------------------------------------------ + void curve3_div::init(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + m_points.remove_all(); + m_distance_tolerance_square = 0.5 / m_approximation_scale; + m_distance_tolerance_square *= m_distance_tolerance_square; + bezier(x1, y1, x2, y2, x3, y3); + m_count = 0; + } + + //------------------------------------------------------------------------ + void curve3_div::recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + unsigned level) + { + if(level > curve_recursion_limit) + { + return; + } + + // Calculate all the mid-points of the line segments + //---------------------- + double x12 = (x1 + x2) / 2; + double y12 = (y1 + y2) / 2; + double x23 = (x2 + x3) / 2; + double y23 = (y2 + y3) / 2; + double x123 = (x12 + x23) / 2; + double y123 = (y12 + y23) / 2; + + double dx = x3-x1; + double dy = y3-y1; + double d = std::fabs(((x2 - x3) * dy - (y2 - y3) * dx)); + double da; + + if(d > curve_collinearity_epsilon) + { + // Regular case + //----------------- + if(d * d <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + // If the curvature doesn't exceed the distance_tolerance value + // we tend to finish subdivisions. + //---------------------- + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x123, y123)); + return; + } + + // Angle & Cusp Condition + //---------------------- + da = std::fabs(std::atan2(y3 - y2, x3 - x2) - std::atan2(y2 - y1, x2 - x1)); + if(da >= pi) da = 2*pi - da; + + if(da < m_angle_tolerance) + { + // Finally we can stop the recursion + //---------------------- + m_points.add(point_d(x123, y123)); + return; + } + } + } + else + { + // Collinear case + //------------------ + da = dx*dx + dy*dy; + if(da == 0) + { + d = calc_sq_distance(x1, y1, x2, y2); + } + else + { + d = ((x2 - x1)*dx + (y2 - y1)*dy) / da; + if(d > 0 && d < 1) + { + // Simple collinear case, 1---2---3 + // We can leave just two endpoints + return; + } + if(d <= 0) d = calc_sq_distance(x2, y2, x1, y1); + else if(d >= 1) d = calc_sq_distance(x2, y2, x3, y3); + else d = calc_sq_distance(x2, y2, x1 + d*dx, y1 + d*dy); + } + if(d < m_distance_tolerance_square) + { + m_points.add(point_d(x2, y2)); + return; + } + } + + // Continue subdivision + //---------------------- + recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1); + recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1); + } + + //------------------------------------------------------------------------ + void curve3_div::bezier(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + m_points.add(point_d(x1, y1)); + recursive_bezier(x1, y1, x2, y2, x3, y3, 0); + m_points.add(point_d(x3, y3)); + } + + + + + + //------------------------------------------------------------------------ + void curve4_inc::approximation_scale(double s) + { + m_scale = s; + } + + //------------------------------------------------------------------------ + double curve4_inc::approximation_scale() const + { + return m_scale; + } + +#if defined(_MSC_VER) && _MSC_VER <= 1200 + //------------------------------------------------------------------------ + static double MSC60_fix_ICE(double v) { return v; } +#endif + + //------------------------------------------------------------------------ + void curve4_inc::init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_start_x = x1; + m_start_y = y1; + m_end_x = x4; + m_end_y = y4; + + double dx1 = x2 - x1; + double dy1 = y2 - y1; + double dx2 = x3 - x2; + double dy2 = y3 - y2; + double dx3 = x4 - x3; + double dy3 = y4 - y3; + + double len = (std::sqrt(dx1 * dx1 + dy1 * dy1) + + std::sqrt(dx2 * dx2 + dy2 * dy2) + + std::sqrt(dx3 * dx3 + dy3 * dy3)) * 0.25 * m_scale; + +#if defined(_MSC_VER) && _MSC_VER <= 1200 + m_num_steps = uround(MSC60_fix_ICE(len)); +#else + m_num_steps = uround(len); +#endif + + if(m_num_steps < 4) + { + m_num_steps = 4; + } + + double subdivide_step = 1.0 / m_num_steps; + double subdivide_step2 = subdivide_step * subdivide_step; + double subdivide_step3 = subdivide_step * subdivide_step * subdivide_step; + + double pre1 = 3.0 * subdivide_step; + double pre2 = 3.0 * subdivide_step2; + double pre4 = 6.0 * subdivide_step2; + double pre5 = 6.0 * subdivide_step3; + + double tmp1x = x1 - x2 * 2.0 + x3; + double tmp1y = y1 - y2 * 2.0 + y3; + + double tmp2x = (x2 - x3) * 3.0 - x1 + x4; + double tmp2y = (y2 - y3) * 3.0 - y1 + y4; + + m_saved_fx = m_fx = x1; + m_saved_fy = m_fy = y1; + + m_saved_dfx = m_dfx = (x2 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdivide_step3; + m_saved_dfy = m_dfy = (y2 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdivide_step3; + + m_saved_ddfx = m_ddfx = tmp1x * pre4 + tmp2x * pre5; + m_saved_ddfy = m_ddfy = tmp1y * pre4 + tmp2y * pre5; + + m_dddfx = tmp2x * pre5; + m_dddfy = tmp2y * pre5; + + m_step = m_num_steps; + } + + //------------------------------------------------------------------------ + void curve4_inc::rewind(unsigned) + { + if(m_num_steps == 0) + { + m_step = -1; + return; + } + m_step = m_num_steps; + m_fx = m_saved_fx; + m_fy = m_saved_fy; + m_dfx = m_saved_dfx; + m_dfy = m_saved_dfy; + m_ddfx = m_saved_ddfx; + m_ddfy = m_saved_ddfy; + } + + //------------------------------------------------------------------------ + unsigned curve4_inc::vertex(double* x, double* y) + { + if(m_step < 0) return path_cmd_stop; + if(m_step == m_num_steps) + { + *x = m_start_x; + *y = m_start_y; + --m_step; + return path_cmd_move_to; + } + + if(m_step == 0) + { + *x = m_end_x; + *y = m_end_y; + --m_step; + return path_cmd_line_to; + } + + m_fx += m_dfx; + m_fy += m_dfy; + m_dfx += m_ddfx; + m_dfy += m_ddfy; + m_ddfx += m_dddfx; + m_ddfy += m_dddfy; + + *x = m_fx; + *y = m_fy; + --m_step; + return path_cmd_line_to; + } + + + + + //------------------------------------------------------------------------ + void curve4_div::init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_points.remove_all(); + m_distance_tolerance_square = 0.5 / m_approximation_scale; + m_distance_tolerance_square *= m_distance_tolerance_square; + bezier(x1, y1, x2, y2, x3, y3, x4, y4); + m_count = 0; + } + + //------------------------------------------------------------------------ + void curve4_div::recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4, + unsigned level) + { + if(level > curve_recursion_limit) + { + return; + } + + // Calculate all the mid-points of the line segments + //---------------------- + double x12 = (x1 + x2) / 2; + double y12 = (y1 + y2) / 2; + double x23 = (x2 + x3) / 2; + double y23 = (y2 + y3) / 2; + double x34 = (x3 + x4) / 2; + double y34 = (y3 + y4) / 2; + double x123 = (x12 + x23) / 2; + double y123 = (y12 + y23) / 2; + double x234 = (x23 + x34) / 2; + double y234 = (y23 + y34) / 2; + double x1234 = (x123 + x234) / 2; + double y1234 = (y123 + y234) / 2; + + + // Try to approximate the full cubic curve by a single straight line + //------------------ + double dx = x4-x1; + double dy = y4-y1; + + double d2 = std::fabs(((x2 - x4) * dy - (y2 - y4) * dx)); + double d3 = std::fabs(((x3 - x4) * dy - (y3 - y4) * dx)); + double da1, da2, k; + + switch((int(d2 > curve_collinearity_epsilon) << 1) + + int(d3 > curve_collinearity_epsilon)) + { + case 0: + // All collinear OR p1==p4 + //---------------------- + k = dx*dx + dy*dy; + if(k == 0) + { + d2 = calc_sq_distance(x1, y1, x2, y2); + d3 = calc_sq_distance(x4, y4, x3, y3); + } + else + { + k = 1 / k; + da1 = x2 - x1; + da2 = y2 - y1; + d2 = k * (da1*dx + da2*dy); + da1 = x3 - x1; + da2 = y3 - y1; + d3 = k * (da1*dx + da2*dy); + if(d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1) + { + // Simple collinear case, 1---2---3---4 + // We can leave just two endpoints + return; + } + if(d2 <= 0) d2 = calc_sq_distance(x2, y2, x1, y1); + else if(d2 >= 1) d2 = calc_sq_distance(x2, y2, x4, y4); + else d2 = calc_sq_distance(x2, y2, x1 + d2*dx, y1 + d2*dy); + + if(d3 <= 0) d3 = calc_sq_distance(x3, y3, x1, y1); + else if(d3 >= 1) d3 = calc_sq_distance(x3, y3, x4, y4); + else d3 = calc_sq_distance(x3, y3, x1 + d3*dx, y1 + d3*dy); + } + if(d2 > d3) + { + if(d2 < m_distance_tolerance_square) + { + m_points.add(point_d(x2, y2)); + return; + } + } + else + { + if(d3 < m_distance_tolerance_square) + { + m_points.add(point_d(x3, y3)); + return; + } + } + break; + + case 1: + // p1,p2,p4 are collinear, p3 is significant + //---------------------- + if(d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x23, y23)); + return; + } + + // Angle Condition + //---------------------- + da1 = std::fabs(std::atan2(y4 - y3, x4 - x3) - std::atan2(y3 - y2, x3 - x2)); + if(da1 >= pi) da1 = 2*pi - da1; + + if(da1 < m_angle_tolerance) + { + m_points.add(point_d(x2, y2)); + m_points.add(point_d(x3, y3)); + return; + } + + if(m_cusp_limit != 0.0) + { + if(da1 > m_cusp_limit) + { + m_points.add(point_d(x3, y3)); + return; + } + } + } + break; + + case 2: + // p1,p3,p4 are collinear, p2 is significant + //---------------------- + if(d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x23, y23)); + return; + } + + // Angle Condition + //---------------------- + da1 = std::fabs(std::atan2(y3 - y2, x3 - x2) - std::atan2(y2 - y1, x2 - x1)); + if(da1 >= pi) da1 = 2*pi - da1; + + if(da1 < m_angle_tolerance) + { + m_points.add(point_d(x2, y2)); + m_points.add(point_d(x3, y3)); + return; + } + + if(m_cusp_limit != 0.0) + { + if(da1 > m_cusp_limit) + { + m_points.add(point_d(x2, y2)); + return; + } + } + } + break; + + case 3: + // Regular case + //----------------- + if((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + // If the curvature doesn't exceed the distance_tolerance value + // we tend to finish subdivisions. + //---------------------- + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x23, y23)); + return; + } + + // Angle & Cusp Condition + //---------------------- + k = std::atan2(y3 - y2, x3 - x2); + da1 = std::fabs(k - std::atan2(y2 - y1, x2 - x1)); + da2 = std::fabs(std::atan2(y4 - y3, x4 - x3) - k); + if(da1 >= pi) da1 = 2*pi - da1; + if(da2 >= pi) da2 = 2*pi - da2; + + if(da1 + da2 < m_angle_tolerance) + { + // Finally we can stop the recursion + //---------------------- + m_points.add(point_d(x23, y23)); + return; + } + + if(m_cusp_limit != 0.0) + { + if(da1 > m_cusp_limit) + { + m_points.add(point_d(x2, y2)); + return; + } + + if(da2 > m_cusp_limit) + { + m_points.add(point_d(x3, y3)); + return; + } + } + } + break; + } + + // Continue subdivision + //---------------------- + recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); + recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); + } + + //------------------------------------------------------------------------ + void curve4_div::bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_points.add(point_d(x1, y1)); + recursive_bezier(x1, y1, x2, y2, x3, y3, x4, y4, 0); + m_points.add(point_d(x4, y4)); + } + +} + diff --git a/src/agg_embedded_raster_fonts.cpp b/src/agg_embedded_raster_fonts.cpp new file mode 100644 index 0000000..ee4dc65 --- /dev/null +++ b/src/agg_embedded_raster_fonts.cpp @@ -0,0 +1,10426 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include "agg_embedded_raster_fonts.h" + +namespace agg +{ + + const int8u gse4x6[] = + { + 6, 0, 32, 128-32, + + 0x00,0x00,0x07,0x00,0x0e,0x00,0x15,0x00,0x1c,0x00,0x23,0x00,0x2a,0x00,0x31,0x00,0x38,0x00, + 0x3f,0x00,0x46,0x00,0x4d,0x00,0x54,0x00,0x5b,0x00,0x62,0x00,0x69,0x00,0x70,0x00,0x77,0x00, + 0x7e,0x00,0x85,0x00,0x8c,0x00,0x93,0x00,0x9a,0x00,0xa1,0x00,0xa8,0x00,0xaf,0x00,0xb6,0x00, + 0xbd,0x00,0xc4,0x00,0xcb,0x00,0xd2,0x00,0xd9,0x00,0xe0,0x00,0xe7,0x00,0xee,0x00,0xf5,0x00, + 0xfc,0x00,0x03,0x01,0x0a,0x01,0x11,0x01,0x18,0x01,0x1f,0x01,0x26,0x01,0x2d,0x01,0x34,0x01, + 0x3b,0x01,0x42,0x01,0x49,0x01,0x50,0x01,0x57,0x01,0x5e,0x01,0x65,0x01,0x6c,0x01,0x73,0x01, + 0x7a,0x01,0x81,0x01,0x88,0x01,0x8f,0x01,0x96,0x01,0x9d,0x01,0xa4,0x01,0xab,0x01,0xb2,0x01, + 0xb9,0x01,0xc0,0x01,0xc7,0x01,0xce,0x01,0xd5,0x01,0xdc,0x01,0xe3,0x01,0xea,0x01,0xf1,0x01, + 0xf8,0x01,0xff,0x01,0x06,0x02,0x0d,0x02,0x14,0x02,0x1b,0x02,0x22,0x02,0x29,0x02,0x30,0x02, + 0x37,0x02,0x3e,0x02,0x45,0x02,0x4c,0x02,0x53,0x02,0x5a,0x02,0x61,0x02,0x68,0x02,0x6f,0x02, + 0x76,0x02,0x7d,0x02,0x84,0x02,0x8b,0x02,0x92,0x02,0x99,0x02, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x40,0x40,0x40,0x00,0x40,0x00, + + 4, // 0x22 '"' + 0xa0,0xa0,0x00,0x00,0x00,0x00, + + 4, // 0x23 '#' + 0x60,0xf0,0x60,0xf0,0x60,0x00, + + 4, // 0x24 '$' + 0x40,0x60,0xc0,0x60,0xc0,0x40, + + 4, // 0x25 '%' + 0xa0,0x20,0x40,0x80,0xa0,0x00, + + 4, // 0x26 '&' + 0xe0,0xa0,0x50,0xa0,0xd0,0x00, + + 4, // 0x27 ''' + 0x40,0x40,0x00,0x00,0x00,0x00, + + 4, // 0x28 '(' + 0x20,0x40,0x40,0x40,0x20,0x00, + + 4, // 0x29 ')' + 0x40,0x20,0x20,0x20,0x40,0x00, + + 4, // 0x2a '*' + 0xa0,0x40,0xe0,0x40,0xa0,0x00, + + 4, // 0x2b '+' + 0x40,0x40,0xe0,0x40,0x40,0x00, + + 4, // 0x2c ',' + 0x00,0x00,0x00,0x40,0x40,0x80, + + 4, // 0x2d '-' + 0x00,0x00,0xe0,0x00,0x00,0x00, + + 4, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x40,0x00, + + 4, // 0x2f '/' + 0x10,0x20,0x20,0x40,0x40,0x80, + + 4, // 0x30 '0' + 0xe0,0xa0,0xa0,0xa0,0xe0,0x00, + + 4, // 0x31 '1' + 0x40,0xc0,0x40,0x40,0xe0,0x00, + + 4, // 0x32 '2' + 0xe0,0xa0,0x20,0x40,0xe0,0x00, + + 4, // 0x33 '3' + 0xe0,0x20,0x40,0x20,0xe0,0x00, + + 4, // 0x34 '4' + 0xa0,0xa0,0xe0,0x20,0x20,0x00, + + 4, // 0x35 '5' + 0xe0,0x80,0xc0,0x20,0xc0,0x00, + + 4, // 0x36 '6' + 0x40,0x80,0xe0,0xa0,0xe0,0x00, + + 4, // 0x37 '7' + 0xe0,0xa0,0x20,0x40,0x40,0x00, + + 4, // 0x38 '8' + 0xe0,0xa0,0x40,0xa0,0xe0,0x00, + + 4, // 0x39 '9' + 0xe0,0xa0,0xe0,0x20,0xc0,0x00, + + 4, // 0x3a ':' + 0x00,0x40,0x00,0x40,0x00,0x00, + + 4, // 0x3b ';' + 0x00,0x40,0x00,0x40,0x40,0x80, + + 4, // 0x3c '<' + 0x20,0x40,0x80,0x40,0x20,0x00, + + 4, // 0x3d '=' + 0x00,0xe0,0x00,0xe0,0x00,0x00, + + 4, // 0x3e '>' + 0x80,0x40,0x20,0x40,0x80,0x00, + + 4, // 0x3f '?' + 0xc0,0x20,0x40,0x00,0x40,0x00, + + 4, // 0x40 '@' + 0x40,0xa0,0xe0,0xe0,0x80,0x60, + + 4, // 0x41 'A' + 0x40,0xa0,0xe0,0xa0,0xa0,0x00, + + 4, // 0x42 'B' + 0xc0,0xa0,0xc0,0xa0,0xc0,0x00, + + 4, // 0x43 'C' + 0x60,0x80,0x80,0x80,0x60,0x00, + + 4, // 0x44 'D' + 0xc0,0xa0,0xa0,0xa0,0xc0,0x00, + + 4, // 0x45 'E' + 0xe0,0x80,0xc0,0x80,0xe0,0x00, + + 4, // 0x46 'F' + 0xe0,0x80,0xc0,0x80,0x80,0x00, + + 4, // 0x47 'G' + 0x60,0x80,0xa0,0xa0,0x40,0x00, + + 4, // 0x48 'H' + 0xa0,0xa0,0xe0,0xa0,0xa0,0x00, + + 4, // 0x49 'I' + 0xe0,0x40,0x40,0x40,0xe0,0x00, + + 4, // 0x4a 'J' + 0x20,0x20,0x20,0x20,0xa0,0x40, + + 4, // 0x4b 'K' + 0xa0,0xa0,0xc0,0xc0,0xa0,0x00, + + 4, // 0x4c 'L' + 0x80,0x80,0x80,0x80,0xe0,0x00, + + 4, // 0x4d 'M' + 0xa0,0xe0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x4e 'N' + 0x90,0xd0,0xb0,0x90,0x90,0x00, + + 4, // 0x4f 'O' + 0x40,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x50 'P' + 0xc0,0xa0,0xa0,0xc0,0x80,0x00, + + 4, // 0x51 'Q' + 0x40,0xa0,0xa0,0xa0,0x60,0x00, + + 4, // 0x52 'R' + 0xc0,0xa0,0xa0,0xc0,0xa0,0x00, + + 4, // 0x53 'S' + 0x60,0x80,0x40,0x20,0xc0,0x00, + + 4, // 0x54 'T' + 0xe0,0x40,0x40,0x40,0x40,0x00, + + 4, // 0x55 'U' + 0xa0,0xa0,0xa0,0xa0,0xe0,0x00, + + 4, // 0x56 'V' + 0xa0,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x57 'W' + 0xa0,0xa0,0xa0,0xe0,0xa0,0x00, + + 4, // 0x58 'X' + 0xa0,0xa0,0x40,0xa0,0xa0,0x00, + + 4, // 0x59 'Y' + 0xa0,0xa0,0x40,0x40,0x40,0x00, + + 4, // 0x5a 'Z' + 0xe0,0x20,0x40,0x80,0xe0,0x00, + + 4, // 0x5b '[' + 0xc0,0x80,0x80,0x80,0xc0,0x00, + + 4, // 0x5c '\' + 0x80,0x40,0x40,0x20,0x20,0x10, + + 4, // 0x5d ']' + 0xc0,0x40,0x40,0x40,0xc0,0x00, + + 4, // 0x5e '^' + 0x40,0xa0,0x00,0x00,0x00,0x00, + + 4, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0xf0, + + 4, // 0x60 '`' + 0x40,0x20,0x00,0x00,0x00,0x00, + + 4, // 0x61 'a' + 0x00,0x60,0xa0,0xa0,0x70,0x00, + + 4, // 0x62 'b' + 0x80,0x80,0xc0,0xa0,0xc0,0x00, + + 4, // 0x63 'c' + 0x00,0x60,0x80,0x80,0x60,0x00, + + 4, // 0x64 'd' + 0x20,0x20,0x60,0xa0,0x60,0x00, + + 4, // 0x65 'e' + 0x00,0x40,0xe0,0x80,0x60,0x00, + + 4, // 0x66 'f' + 0x20,0x40,0xe0,0x40,0x40,0x00, + + 4, // 0x67 'g' + 0x00,0x60,0xa0,0x60,0x20,0xc0, + + 4, // 0x68 'h' + 0x80,0x80,0xc0,0xa0,0xa0,0x00, + + 4, // 0x69 'i' + 0x40,0x00,0xc0,0x40,0xe0,0x00, + + 4, // 0x6a 'j' + 0x40,0x00,0xc0,0x40,0x40,0x80, + + 4, // 0x6b 'k' + 0x80,0x80,0xa0,0xc0,0xa0,0x00, + + 4, // 0x6c 'l' + 0xc0,0x40,0x40,0x40,0xe0,0x00, + + 4, // 0x6d 'm' + 0x00,0xa0,0xf0,0xf0,0x90,0x00, + + 4, // 0x6e 'n' + 0x00,0xc0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x6f 'o' + 0x00,0x40,0xa0,0xa0,0x40,0x00, + + 4, // 0x70 'p' + 0x00,0xc0,0xa0,0xc0,0x80,0x80, + + 4, // 0x71 'q' + 0x00,0x60,0xa0,0x60,0x20,0x20, + + 4, // 0x72 'r' + 0x00,0xa0,0x50,0x40,0x40,0x00, + + 4, // 0x73 's' + 0x00,0x60,0xc0,0x20,0xc0,0x00, + + 4, // 0x74 't' + 0x40,0x40,0xe0,0x40,0x60,0x00, + + 4, // 0x75 'u' + 0x00,0xa0,0xa0,0xa0,0x60,0x00, + + 4, // 0x76 'v' + 0x00,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x77 'w' + 0x00,0xa0,0xa0,0xe0,0xa0,0x00, + + 4, // 0x78 'x' + 0x00,0xa0,0x40,0xa0,0xa0,0x00, + + 4, // 0x79 'y' + 0x00,0xa0,0xa0,0x60,0x20,0xc0, + + 4, // 0x7a 'z' + 0x00,0xe0,0x40,0x80,0xe0,0x00, + + 4, // 0x7b '{' + 0x30,0x20,0xc0,0x20,0x30,0x00, + + 4, // 0x7c '|' + 0x40,0x40,0x00,0x40,0x40,0x40, + + 4, // 0x7d '}' + 0xc0,0x40,0x30,0x40,0xc0,0x00, + + 4, // 0x7e '~' + 0x50,0xa0,0x00,0x00,0x00,0x00, + + 4, // 0x7f '' + 0x00,0x60,0x90,0xf0,0x00,0x00, + 0 + }; + + const int8u gse4x8[] = + { + 8, 0, 32, 128-32, + + 0x00,0x00,0x09,0x00,0x12,0x00,0x1b,0x00,0x24,0x00,0x2d,0x00,0x36,0x00,0x3f,0x00,0x48,0x00, + 0x51,0x00,0x5a,0x00,0x63,0x00,0x6c,0x00,0x75,0x00,0x7e,0x00,0x87,0x00,0x90,0x00,0x99,0x00, + 0xa2,0x00,0xab,0x00,0xb4,0x00,0xbd,0x00,0xc6,0x00,0xcf,0x00,0xd8,0x00,0xe1,0x00,0xea,0x00, + 0xf3,0x00,0xfc,0x00,0x05,0x01,0x0e,0x01,0x17,0x01,0x20,0x01,0x29,0x01,0x32,0x01,0x3b,0x01, + 0x44,0x01,0x4d,0x01,0x56,0x01,0x5f,0x01,0x68,0x01,0x71,0x01,0x7a,0x01,0x83,0x01,0x8c,0x01, + 0x95,0x01,0x9e,0x01,0xa7,0x01,0xb0,0x01,0xb9,0x01,0xc2,0x01,0xcb,0x01,0xd4,0x01,0xdd,0x01, + 0xe6,0x01,0xef,0x01,0xf8,0x01,0x01,0x02,0x0a,0x02,0x13,0x02,0x1c,0x02,0x25,0x02,0x2e,0x02, + 0x37,0x02,0x40,0x02,0x49,0x02,0x52,0x02,0x5b,0x02,0x64,0x02,0x6d,0x02,0x76,0x02,0x7f,0x02, + 0x88,0x02,0x91,0x02,0x9a,0x02,0xa3,0x02,0xac,0x02,0xb5,0x02,0xbe,0x02,0xc7,0x02,0xd0,0x02, + 0xd9,0x02,0xe2,0x02,0xeb,0x02,0xf4,0x02,0xfd,0x02,0x06,0x03,0x0f,0x03,0x18,0x03,0x21,0x03, + 0x2a,0x03,0x33,0x03,0x3c,0x03,0x45,0x03,0x4e,0x03,0x57,0x03, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x40,0x40,0x40,0x40,0x00,0x40,0x00, + + 4, // 0x22 '"' + 0x00,0xa0,0xa0,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x23 '#' + 0x60,0x60,0xf0,0x60,0x60,0xf0,0x60,0x60, + + 4, // 0x24 '$' + 0x40,0x60,0xc0,0xc0,0x60,0x60,0xc0,0x40, + + 4, // 0x25 '%' + 0x00,0xa0,0x20,0x40,0x40,0x80,0xa0,0x00, + + 4, // 0x26 '&' + 0x00,0x40,0xa0,0xa0,0x40,0xb0,0xa0,0x70, + + 4, // 0x27 ''' + 0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x28 '(' + 0x20,0x40,0x80,0x80,0x80,0x80,0x40,0x20, + + 4, // 0x29 ')' + 0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80, + + 4, // 0x2a '*' + 0x00,0xa0,0x40,0xe0,0x40,0xa0,0x00,0x00, + + 4, // 0x2b '+' + 0x00,0x40,0x40,0xe0,0x40,0x40,0x00,0x00, + + 4, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80, + + 4, // 0x2d '-' + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + + 4, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, + + 4, // 0x2f '/' + 0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80, + + 4, // 0x30 '0' + 0x00,0xe0,0xa0,0xa0,0xa0,0xa0,0xe0,0x00, + + 4, // 0x31 '1' + 0x00,0x40,0xc0,0x40,0x40,0x40,0xe0,0x00, + + 4, // 0x32 '2' + 0x00,0xe0,0xa0,0x20,0x40,0x80,0xe0,0x00, + + 4, // 0x33 '3' + 0x00,0xe0,0x20,0x40,0x20,0x20,0xe0,0x00, + + 4, // 0x34 '4' + 0x00,0x60,0xa0,0xa0,0xf0,0x20,0x20,0x00, + + 4, // 0x35 '5' + 0x00,0xe0,0x80,0xc0,0x20,0x20,0xc0,0x00, + + 4, // 0x36 '6' + 0x00,0x40,0x80,0xe0,0xa0,0xa0,0xe0,0x00, + + 4, // 0x37 '7' + 0x00,0xe0,0xa0,0x20,0x40,0x40,0x40,0x00, + + 4, // 0x38 '8' + 0x00,0xe0,0xa0,0x40,0xa0,0xa0,0xe0,0x00, + + 4, // 0x39 '9' + 0x00,0xe0,0xa0,0xe0,0x20,0x20,0x40,0x00, + + 4, // 0x3a ':' + 0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00, + + 4, // 0x3b ';' + 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x80, + + 4, // 0x3c '<' + 0x00,0x20,0x40,0x80,0x40,0x20,0x00,0x00, + + 4, // 0x3d '=' + 0x00,0x00,0xe0,0x00,0xe0,0x00,0x00,0x00, + + 4, // 0x3e '>' + 0x00,0x80,0x40,0x20,0x40,0x80,0x00,0x00, + + 4, // 0x3f '?' + 0x00,0x40,0xa0,0x20,0x40,0x00,0x40,0x00, + + 4, // 0x40 '@' + 0x00,0x40,0xa0,0xe0,0xe0,0x80,0x60,0x00, + + 4, // 0x41 'A' + 0x00,0x40,0xa0,0xa0,0xe0,0xa0,0xa0,0x00, + + 4, // 0x42 'B' + 0x00,0xc0,0xa0,0xc0,0xa0,0xa0,0xc0,0x00, + + 4, // 0x43 'C' + 0x00,0x40,0xa0,0x80,0x80,0xa0,0x40,0x00, + + 4, // 0x44 'D' + 0x00,0xc0,0xa0,0xa0,0xa0,0xa0,0xc0,0x00, + + 4, // 0x45 'E' + 0x00,0xe0,0x80,0xc0,0x80,0x80,0xe0,0x00, + + 4, // 0x46 'F' + 0x00,0xe0,0x80,0xc0,0x80,0x80,0x80,0x00, + + 4, // 0x47 'G' + 0x00,0x60,0x80,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x48 'H' + 0x00,0xa0,0xa0,0xe0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x49 'I' + 0x00,0xe0,0x40,0x40,0x40,0x40,0xe0,0x00, + + 4, // 0x4a 'J' + 0x00,0x20,0x20,0x20,0x20,0xa0,0x40,0x00, + + 4, // 0x4b 'K' + 0x00,0xa0,0xa0,0xc0,0xc0,0xa0,0xa0,0x00, + + 4, // 0x4c 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0xe0,0x00, + + 4, // 0x4d 'M' + 0x00,0xa0,0xe0,0xa0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x4e 'N' + 0x00,0x90,0x90,0xd0,0xb0,0x90,0x90,0x00, + + 4, // 0x4f 'O' + 0x00,0x40,0xa0,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x50 'P' + 0x00,0xc0,0xa0,0xa0,0xc0,0x80,0x80,0x00, + + 4, // 0x51 'Q' + 0x00,0x40,0xa0,0xa0,0xa0,0xa0,0x60,0x00, + + 4, // 0x52 'R' + 0x00,0xc0,0xa0,0xa0,0xc0,0xc0,0xa0,0x00, + + 4, // 0x53 'S' + 0x00,0x60,0x80,0x40,0x20,0x20,0xc0,0x00, + + 4, // 0x54 'T' + 0x00,0xe0,0x40,0x40,0x40,0x40,0x40,0x00, + + 4, // 0x55 'U' + 0x00,0xa0,0xa0,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x56 'V' + 0x00,0xa0,0xa0,0xa0,0xa0,0x40,0x40,0x00, + + 4, // 0x57 'W' + 0x00,0xa0,0xa0,0xa0,0xa0,0xe0,0xa0,0x00, + + 4, // 0x58 'X' + 0x00,0xa0,0xa0,0x40,0xa0,0xa0,0xa0,0x00, + + 4, // 0x59 'Y' + 0x00,0xa0,0xa0,0x40,0x40,0x40,0x40,0x00, + + 4, // 0x5a 'Z' + 0x00,0xe0,0x20,0x40,0x40,0x80,0xe0,0x00, + + 4, // 0x5b '[' + 0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0xc0, + + 4, // 0x5c '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10, + + 4, // 0x5d ']' + 0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0xc0, + + 4, // 0x5e '^' + 0x00,0x40,0xa0,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0, + + 4, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x61 'a' + 0x00,0x00,0x60,0xa0,0xa0,0xa0,0x70,0x00, + + 4, // 0x62 'b' + 0x00,0x80,0x80,0xc0,0xa0,0xa0,0xc0,0x00, + + 4, // 0x63 'c' + 0x00,0x00,0x40,0xa0,0x80,0xa0,0x40,0x00, + + 4, // 0x64 'd' + 0x00,0x20,0x20,0x60,0xa0,0xa0,0x60,0x00, + + 4, // 0x65 'e' + 0x00,0x00,0x40,0xa0,0xe0,0x80,0x60,0x00, + + 4, // 0x66 'f' + 0x00,0x20,0x40,0x40,0xe0,0x40,0x40,0x00, + + 4, // 0x67 'g' + 0x00,0x00,0x60,0xa0,0xa0,0x60,0x20,0xc0, + + 4, // 0x68 'h' + 0x00,0x80,0x80,0xc0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x69 'i' + 0x00,0x40,0x00,0xc0,0x40,0x40,0xe0,0x00, + + 4, // 0x6a 'j' + 0x00,0x40,0x00,0xc0,0x40,0x40,0x40,0x80, + + 4, // 0x6b 'k' + 0x00,0x80,0x80,0xa0,0xc0,0xc0,0xa0,0x00, + + 4, // 0x6c 'l' + 0x00,0xc0,0x40,0x40,0x40,0x40,0xe0,0x00, + + 4, // 0x6d 'm' + 0x00,0x00,0xa0,0xf0,0xf0,0xf0,0x90,0x00, + + 4, // 0x6e 'n' + 0x00,0x00,0xc0,0xa0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x6f 'o' + 0x00,0x00,0x40,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x70 'p' + 0x00,0x00,0xc0,0xa0,0xa0,0xc0,0x80,0x80, + + 4, // 0x71 'q' + 0x00,0x00,0x60,0xa0,0xa0,0x60,0x20,0x20, + + 4, // 0x72 'r' + 0x00,0x00,0xa0,0x50,0x40,0x40,0x40,0x00, + + 4, // 0x73 's' + 0x00,0x00,0x60,0x80,0x40,0x20,0xc0,0x00, + + 4, // 0x74 't' + 0x00,0x40,0x40,0xe0,0x40,0x40,0x20,0x00, + + 4, // 0x75 'u' + 0x00,0x00,0xa0,0xa0,0xa0,0xa0,0x60,0x00, + + 4, // 0x76 'v' + 0x00,0x00,0xa0,0xa0,0xa0,0x40,0x40,0x00, + + 4, // 0x77 'w' + 0x00,0x00,0xa0,0xa0,0xa0,0xe0,0xa0,0x00, + + 4, // 0x78 'x' + 0x00,0x00,0xa0,0xa0,0x40,0xa0,0xa0,0x00, + + 4, // 0x79 'y' + 0x00,0x00,0xa0,0xa0,0xa0,0x60,0x20,0xc0, + + 4, // 0x7a 'z' + 0x00,0x00,0xe0,0x20,0x40,0x80,0xe0,0x00, + + 4, // 0x7b '{' + 0x10,0x20,0x20,0xc0,0x20,0x20,0x10,0x00, + + 4, // 0x7c '|' + 0x00,0x40,0x40,0x40,0x00,0x40,0x40,0x40, + + 4, // 0x7d '}' + 0x80,0x40,0x40,0x30,0x40,0x40,0x80,0x00, + + 4, // 0x7e '~' + 0x00,0x50,0xa0,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x7f '' + 0x00,0x00,0x00,0x60,0x90,0xf0,0x00,0x00, + 0 + }; + + const int8u gse5x7[] = + { + 7, 0, 32, 128-32, + + 0x00,0x00,0x08,0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x38,0x00,0x40,0x00, + 0x48,0x00,0x50,0x00,0x58,0x00,0x60,0x00,0x68,0x00,0x70,0x00,0x78,0x00,0x80,0x00,0x88,0x00, + 0x90,0x00,0x98,0x00,0xa0,0x00,0xa8,0x00,0xb0,0x00,0xb8,0x00,0xc0,0x00,0xc8,0x00,0xd0,0x00, + 0xd8,0x00,0xe0,0x00,0xe8,0x00,0xf0,0x00,0xf8,0x00,0x00,0x01,0x08,0x01,0x10,0x01,0x18,0x01, + 0x20,0x01,0x28,0x01,0x30,0x01,0x38,0x01,0x40,0x01,0x48,0x01,0x50,0x01,0x58,0x01,0x60,0x01, + 0x68,0x01,0x70,0x01,0x78,0x01,0x80,0x01,0x88,0x01,0x90,0x01,0x98,0x01,0xa0,0x01,0xa8,0x01, + 0xb0,0x01,0xb8,0x01,0xc0,0x01,0xc8,0x01,0xd0,0x01,0xd8,0x01,0xe0,0x01,0xe8,0x01,0xf0,0x01, + 0xf8,0x01,0x00,0x02,0x08,0x02,0x10,0x02,0x18,0x02,0x20,0x02,0x28,0x02,0x30,0x02,0x38,0x02, + 0x40,0x02,0x48,0x02,0x50,0x02,0x58,0x02,0x60,0x02,0x68,0x02,0x70,0x02,0x78,0x02,0x80,0x02, + 0x88,0x02,0x90,0x02,0x98,0x02,0xa0,0x02,0xa8,0x02,0xb0,0x02,0xb8,0x02,0xc0,0x02,0xc8,0x02, + 0xd0,0x02,0xd8,0x02,0xe0,0x02,0xe8,0x02,0xf0,0x02,0xf8,0x02, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x00,0x20,0x00, + + 5, // 0x22 '"' + 0x00,0x50,0x50,0x00,0x00,0x00,0x00, + + 5, // 0x23 '#' + 0x00,0x50,0xf8,0x50,0xf8,0x50,0x00, + + 5, // 0x24 '$' + 0x20,0x78,0xa0,0x70,0x28,0xf0,0x20, + + 5, // 0x25 '%' + 0x00,0x88,0x10,0x20,0x40,0x88,0x00, + + 5, // 0x26 '&' + 0x00,0x40,0xa0,0x68,0x90,0x68,0x00, + + 5, // 0x27 ''' + 0x00,0x20,0x20,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x40,0x40,0x40,0x20,0x10, + + 5, // 0x29 ')' + 0x80,0x40,0x20,0x20,0x20,0x40,0x80, + + 5, // 0x2a '*' + 0x00,0x20,0xa8,0x70,0xa8,0x20,0x00, + + 5, // 0x2b '+' + 0x00,0x20,0x20,0xf8,0x20,0x20,0x00, + + 5, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x20,0x20,0x40, + + 5, // 0x2d '-' + 0x00,0x00,0x00,0xf0,0x00,0x00,0x00, + + 5, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x40,0x00, + + 5, // 0x2f '/' + 0x00,0x08,0x10,0x20,0x40,0x80,0x00, + + 5, // 0x30 '0' + 0x00,0x60,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x70,0x00, + + 5, // 0x32 '2' + 0x00,0x60,0x90,0x20,0x40,0xf0,0x00, + + 5, // 0x33 '3' + 0x00,0xf0,0x20,0x60,0x10,0xe0,0x00, + + 5, // 0x34 '4' + 0x00,0x30,0x50,0x90,0xf0,0x10,0x00, + + 5, // 0x35 '5' + 0x00,0xf0,0x80,0xe0,0x10,0xe0,0x00, + + 5, // 0x36 '6' + 0x00,0x60,0x80,0xe0,0x90,0x60,0x00, + + 5, // 0x37 '7' + 0x00,0xf0,0x90,0x20,0x40,0x40,0x00, + + 5, // 0x38 '8' + 0x00,0x60,0x90,0x60,0x90,0x60,0x00, + + 5, // 0x39 '9' + 0x00,0x60,0x90,0x70,0x10,0x60,0x00, + + 5, // 0x3a ':' + 0x00,0x00,0x20,0x00,0x20,0x00,0x00, + + 5, // 0x3b ';' + 0x00,0x00,0x20,0x00,0x20,0x20,0x40, + + 5, // 0x3c '<' + 0x00,0x10,0x20,0x40,0x20,0x10,0x00, + + 5, // 0x3d '=' + 0x00,0x00,0xf0,0x00,0xf0,0x00,0x00, + + 5, // 0x3e '>' + 0x00,0x80,0x40,0x20,0x40,0x80,0x00, + + 5, // 0x3f '?' + 0x00,0x60,0x90,0x20,0x00,0x20,0x00, + + 5, // 0x40 '@' + 0x00,0x60,0x90,0xb0,0x80,0x70,0x00, + + 5, // 0x41 'A' + 0x00,0x60,0x90,0xf0,0x90,0x90,0x00, + + 5, // 0x42 'B' + 0x00,0xe0,0x90,0xe0,0x90,0xe0,0x00, + + 5, // 0x43 'C' + 0x00,0x60,0x90,0x80,0x90,0x60,0x00, + + 5, // 0x44 'D' + 0x00,0xe0,0x90,0x90,0x90,0xe0,0x00, + + 5, // 0x45 'E' + 0x00,0xf0,0x80,0xe0,0x80,0xf0,0x00, + + 5, // 0x46 'F' + 0x00,0xf0,0x80,0xe0,0x80,0x80,0x00, + + 5, // 0x47 'G' + 0x00,0x70,0x80,0xb0,0x90,0x60,0x00, + + 5, // 0x48 'H' + 0x00,0x90,0x90,0xf0,0x90,0x90,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x4a 'J' + 0x00,0x70,0x20,0x20,0xa0,0x40,0x00, + + 5, // 0x4b 'K' + 0x00,0x90,0xa0,0xc0,0xa0,0x90,0x00, + + 5, // 0x4c 'L' + 0x00,0x80,0x80,0x80,0x80,0xf0,0x00, + + 5, // 0x4d 'M' + 0x00,0x90,0xf0,0x90,0x90,0x90,0x00, + + 5, // 0x4e 'N' + 0x00,0x90,0xd0,0xb0,0x90,0x90,0x00, + + 5, // 0x4f 'O' + 0x00,0x60,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x50 'P' + 0x00,0xe0,0x90,0xe0,0x80,0x80,0x00, + + 5, // 0x51 'Q' + 0x00,0x60,0x90,0x90,0xa0,0x50,0x00, + + 5, // 0x52 'R' + 0x00,0xe0,0x90,0xe0,0xa0,0x90,0x00, + + 5, // 0x53 'S' + 0x00,0x70,0x80,0x60,0x10,0xe0,0x00, + + 5, // 0x54 'T' + 0x00,0x70,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x55 'U' + 0x00,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x56 'V' + 0x00,0x50,0x50,0x50,0x20,0x20,0x00, + + 5, // 0x57 'W' + 0x00,0x90,0x90,0x90,0xf0,0x90,0x00, + + 5, // 0x58 'X' + 0x00,0x90,0x90,0x60,0x90,0x90,0x00, + + 5, // 0x59 'Y' + 0x00,0x50,0x50,0x20,0x20,0x20,0x00, + + 5, // 0x5a 'Z' + 0x00,0xf0,0x10,0x20,0x40,0xf0,0x00, + + 5, // 0x5b '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x70, + + 5, // 0x5c '\' + 0x00,0x80,0x40,0x20,0x10,0x08,0x00, + + 5, // 0x5d ']' + 0xe0,0x20,0x20,0x20,0x20,0x20,0xe0, + + 5, // 0x5e '^' + 0x00,0x20,0x50,0x00,0x00,0x00,0x00, + + 5, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0xf8,0x00, + + 5, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00, + + 5, // 0x61 'a' + 0x00,0x00,0x60,0xa0,0xa0,0x50,0x00, + + 5, // 0x62 'b' + 0x00,0x80,0x80,0xe0,0x90,0xe0,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x70,0x80,0x80,0x70,0x00, + + 5, // 0x64 'd' + 0x00,0x10,0x10,0x70,0x90,0x70,0x00, + + 5, // 0x65 'e' + 0x00,0x00,0x60,0xf0,0x80,0x70,0x00, + + 5, // 0x66 'f' + 0x00,0x30,0x40,0xe0,0x40,0x40,0x00, + + 5, // 0x67 'g' + 0x00,0x00,0x70,0x90,0x70,0x10,0x60, + + 5, // 0x68 'h' + 0x00,0x80,0x80,0xe0,0x90,0x90,0x00, + + 5, // 0x69 'i' + 0x20,0x00,0x60,0x20,0x20,0x70,0x00, + + 5, // 0x6a 'j' + 0x20,0x00,0x60,0x20,0x20,0xa0,0x40, + + 5, // 0x6b 'k' + 0x80,0x80,0x90,0xa0,0xe0,0x90,0x00, + + 5, // 0x6c 'l' + 0x00,0x60,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x6d 'm' + 0x00,0x00,0xa0,0xf0,0xf0,0x90,0x00, + + 5, // 0x6e 'n' + 0x00,0x00,0xa0,0xd0,0x90,0x90,0x00, + + 5, // 0x6f 'o' + 0x00,0x00,0x60,0x90,0x90,0x60,0x00, + + 5, // 0x70 'p' + 0x00,0x00,0xe0,0x90,0xe0,0x80,0x80, + + 5, // 0x71 'q' + 0x00,0x00,0x70,0x90,0x70,0x10,0x10, + + 5, // 0x72 'r' + 0x00,0x00,0xe0,0x90,0x80,0x80,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x70,0xe0,0x10,0xe0,0x00, + + 5, // 0x74 't' + 0x40,0x40,0xe0,0x40,0x40,0x70,0x00, + + 5, // 0x75 'u' + 0x00,0x00,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x76 'v' + 0x00,0x00,0x50,0x50,0x50,0x20,0x00, + + 5, // 0x77 'w' + 0x00,0x00,0x90,0x90,0xf0,0x90,0x00, + + 5, // 0x78 'x' + 0x00,0x00,0x90,0x60,0x60,0x90,0x00, + + 5, // 0x79 'y' + 0x00,0x00,0x90,0x90,0x70,0x10,0x60, + + 5, // 0x7a 'z' + 0x00,0x00,0xf0,0x20,0x40,0xf0,0x00, + + 5, // 0x7b '{' + 0x10,0x20,0x20,0xc0,0x20,0x20,0x10, + + 5, // 0x7c '|' + 0x20,0x20,0x20,0x00,0x20,0x20,0x20, + + 5, // 0x7d '}' + 0x40,0x20,0x20,0x18,0x20,0x20,0x40, + + 5, // 0x7e '~' + 0x00,0x40,0xa8,0x10,0x00,0x00,0x00, + + 5, // 0x7f '' + 0x00,0x00,0x20,0x50,0x88,0xf8,0x00, + 0 + }; + + const int8u gse5x9[] = + { + 9, 0, 32, 128-32, + + 0x00,0x00,0x0a,0x00,0x14,0x00,0x1e,0x00,0x28,0x00,0x32,0x00,0x3c,0x00,0x46,0x00,0x50,0x00, + 0x5a,0x00,0x64,0x00,0x6e,0x00,0x78,0x00,0x82,0x00,0x8c,0x00,0x96,0x00,0xa0,0x00,0xaa,0x00, + 0xb4,0x00,0xbe,0x00,0xc8,0x00,0xd2,0x00,0xdc,0x00,0xe6,0x00,0xf0,0x00,0xfa,0x00,0x04,0x01, + 0x0e,0x01,0x18,0x01,0x22,0x01,0x2c,0x01,0x36,0x01,0x40,0x01,0x4a,0x01,0x54,0x01,0x5e,0x01, + 0x68,0x01,0x72,0x01,0x7c,0x01,0x86,0x01,0x90,0x01,0x9a,0x01,0xa4,0x01,0xae,0x01,0xb8,0x01, + 0xc2,0x01,0xcc,0x01,0xd6,0x01,0xe0,0x01,0xea,0x01,0xf4,0x01,0xfe,0x01,0x08,0x02,0x12,0x02, + 0x1c,0x02,0x26,0x02,0x30,0x02,0x3a,0x02,0x44,0x02,0x4e,0x02,0x58,0x02,0x62,0x02,0x6c,0x02, + 0x76,0x02,0x80,0x02,0x8a,0x02,0x94,0x02,0x9e,0x02,0xa8,0x02,0xb2,0x02,0xbc,0x02,0xc6,0x02, + 0xd0,0x02,0xda,0x02,0xe4,0x02,0xee,0x02,0xf8,0x02,0x02,0x03,0x0c,0x03,0x16,0x03,0x20,0x03, + 0x2a,0x03,0x34,0x03,0x3e,0x03,0x48,0x03,0x52,0x03,0x5c,0x03,0x66,0x03,0x70,0x03,0x7a,0x03, + 0x84,0x03,0x8e,0x03,0x98,0x03,0xa2,0x03,0xac,0x03,0xb6,0x03, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, + + 5, // 0x22 '"' + 0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x23 '#' + 0x00,0x50,0x50,0xf8,0x50,0xf8,0x50,0x50,0x00, + + 5, // 0x24 '$' + 0x00,0x20,0x78,0xa0,0x70,0x28,0xf0,0x20,0x00, + + 5, // 0x25 '%' + 0x00,0xc8,0xc8,0x10,0x20,0x40,0x98,0x98,0x00, + + 5, // 0x26 '&' + 0x00,0x40,0xa0,0xa0,0x40,0xa8,0x90,0x68,0x00, + + 5, // 0x27 ''' + 0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10, + + 5, // 0x29 ')' + 0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80, + + 5, // 0x2a '*' + 0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00, + + 5, // 0x2b '+' + 0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x00,0x00, + + 5, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x40, + + 5, // 0x2d '-' + 0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00, + + 5, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, + + 5, // 0x2f '/' + 0x00,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80, + + 5, // 0x30 '0' + 0x00,0x60,0x90,0xb0,0xd0,0x90,0x90,0x60,0x00, + + 5, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x32 '2' + 0x00,0x60,0x90,0x10,0x20,0x40,0x80,0xf0,0x00, + + 5, // 0x33 '3' + 0x00,0xf0,0x10,0x20,0x60,0x10,0x90,0x60,0x00, + + 5, // 0x34 '4' + 0x00,0x30,0x50,0x90,0x90,0xf8,0x10,0x10,0x00, + + 5, // 0x35 '5' + 0x00,0xf0,0x80,0xe0,0x10,0x10,0x10,0xe0,0x00, + + 5, // 0x36 '6' + 0x00,0x60,0x80,0xe0,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x37 '7' + 0x00,0xf0,0x90,0x10,0x20,0x40,0x40,0x40,0x00, + + 5, // 0x38 '8' + 0x00,0x60,0x90,0x90,0x60,0x90,0x90,0x60,0x00, + + 5, // 0x39 '9' + 0x00,0x60,0x90,0x90,0x70,0x10,0x90,0x60,0x00, + + 5, // 0x3a ':' + 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00, + + 5, // 0x3b ';' + 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x20,0x40, + + 5, // 0x3c '<' + 0x00,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00, + + 5, // 0x3d '=' + 0x00,0x00,0x00,0xf0,0x00,0xf0,0x00,0x00,0x00, + + 5, // 0x3e '>' + 0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0x00, + + 5, // 0x3f '?' + 0x00,0x60,0x90,0x10,0x20,0x20,0x00,0x20,0x00, + + 5, // 0x40 '@' + 0x00,0x60,0x90,0xb0,0xb0,0xb0,0x80,0x70,0x00, + + 5, // 0x41 'A' + 0x00,0x60,0x90,0x90,0xf0,0x90,0x90,0x90,0x00, + + 5, // 0x42 'B' + 0x00,0xe0,0x90,0x90,0xe0,0x90,0x90,0xe0,0x00, + + 5, // 0x43 'C' + 0x00,0x60,0x90,0x80,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x44 'D' + 0x00,0xe0,0x90,0x90,0x90,0x90,0x90,0xe0,0x00, + + 5, // 0x45 'E' + 0x00,0xf0,0x80,0x80,0xe0,0x80,0x80,0xf0,0x00, + + 5, // 0x46 'F' + 0x00,0xf0,0x80,0x80,0xe0,0x80,0x80,0x80,0x00, + + 5, // 0x47 'G' + 0x00,0x60,0x90,0x80,0xb0,0x90,0x90,0x60,0x00, + + 5, // 0x48 'H' + 0x00,0x90,0x90,0x90,0xf0,0x90,0x90,0x90,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x4a 'J' + 0x00,0x70,0x20,0x20,0x20,0x20,0xa0,0x40,0x00, + + 5, // 0x4b 'K' + 0x00,0x90,0x90,0xa0,0xc0,0xa0,0x90,0x90,0x00, + + 5, // 0x4c 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xf0,0x00, + + 5, // 0x4d 'M' + 0x00,0x90,0xf0,0x90,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x4e 'N' + 0x00,0x90,0x90,0xd0,0xb0,0x90,0x90,0x90,0x00, + + 5, // 0x4f 'O' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x50 'P' + 0x00,0xe0,0x90,0x90,0xe0,0x80,0x80,0x80,0x00, + + 5, // 0x51 'Q' + 0x00,0x60,0x90,0x90,0x90,0x90,0xa0,0x50,0x00, + + 5, // 0x52 'R' + 0x00,0xe0,0x90,0x90,0xe0,0xa0,0x90,0x90,0x00, + + 5, // 0x53 'S' + 0x00,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x00, + + 5, // 0x54 'T' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x55 'U' + 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x56 'V' + 0x00,0x50,0x50,0x50,0x50,0x50,0x20,0x20,0x00, + + 5, // 0x57 'W' + 0x00,0x90,0x90,0x90,0x90,0x90,0xf0,0x90,0x00, + + 5, // 0x58 'X' + 0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00, + + 5, // 0x59 'Y' + 0x00,0x50,0x50,0x50,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x5a 'Z' + 0x00,0xf0,0x10,0x10,0x20,0x40,0x80,0xf0,0x00, + + 5, // 0x5b '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, + + 5, // 0x5c '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x00, + + 5, // 0x5d ']' + 0xe0,0x20,0x20,0x20,0x20,0x20,0x20,0xe0,0x00, + + 5, // 0x5e '^' + 0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00, + + 5, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x61 'a' + 0x00,0x00,0x60,0x10,0x70,0x90,0x90,0x70,0x00, + + 5, // 0x62 'b' + 0x00,0x80,0x80,0xe0,0x90,0x90,0x90,0xe0,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x60,0x90,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x64 'd' + 0x00,0x10,0x10,0x70,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x65 'e' + 0x00,0x00,0x60,0x90,0xf0,0x80,0x80,0x70,0x00, + + 5, // 0x66 'f' + 0x00,0x30,0x40,0x40,0xe0,0x40,0x40,0x40,0x00, + + 5, // 0x67 'g' + 0x00,0x00,0x70,0x90,0x90,0x70,0x10,0x90,0x60, + + 5, // 0x68 'h' + 0x00,0x80,0x80,0xe0,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x69 'i' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x6a 'j' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0xa0,0x40, + + 5, // 0x6b 'k' + 0x00,0x80,0x80,0x90,0xa0,0xc0,0xa0,0x90,0x00, + + 5, // 0x6c 'l' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x6d 'm' + 0x00,0x00,0xa0,0xf0,0xf0,0xf0,0x90,0x90,0x00, + + 5, // 0x6e 'n' + 0x00,0x00,0xa0,0xd0,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x6f 'o' + 0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x70 'p' + 0x00,0x00,0xe0,0x90,0x90,0x90,0xe0,0x80,0x80, + + 5, // 0x71 'q' + 0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0x10, + + 5, // 0x72 'r' + 0x00,0x00,0xe0,0x90,0x80,0x80,0x80,0x80,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x60,0x90,0x40,0x20,0x90,0x60,0x00, + + 5, // 0x74 't' + 0x00,0x40,0x40,0xe0,0x40,0x40,0x50,0x20,0x00, + + 5, // 0x75 'u' + 0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x76 'v' + 0x00,0x00,0x50,0x50,0x50,0x50,0x20,0x20,0x00, + + 5, // 0x77 'w' + 0x00,0x00,0x90,0x90,0x90,0x90,0xf0,0x90,0x00, + + 5, // 0x78 'x' + 0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x00, + + 5, // 0x79 'y' + 0x00,0x00,0x90,0x90,0x90,0x90,0x70,0x10,0xe0, + + 5, // 0x7a 'z' + 0x00,0x00,0xf0,0x10,0x20,0x40,0x80,0xf0,0x00, + + 5, // 0x7b '{' + 0x10,0x20,0x20,0x20,0xc0,0x20,0x20,0x20,0x10, + + 5, // 0x7c '|' + 0x00,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00, + + 5, // 0x7d '}' + 0x80,0x40,0x40,0x40,0x30,0x40,0x40,0x40,0x80, + + 5, // 0x7e '~' + 0x00,0x40,0xa8,0x10,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x7f '' + 0x00,0x00,0x00,0x20,0x50,0x88,0xf8,0x00,0x00, + 0 + }; + + const int8u gse6x12[] = + { + 12, 0, 32, 128-32, + + 0x00,0x00,0x0d,0x00,0x1a,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4e,0x00,0x5b,0x00,0x68,0x00, + 0x75,0x00,0x82,0x00,0x8f,0x00,0x9c,0x00,0xa9,0x00,0xb6,0x00,0xc3,0x00,0xd0,0x00,0xdd,0x00, + 0xea,0x00,0xf7,0x00,0x04,0x01,0x11,0x01,0x1e,0x01,0x2b,0x01,0x38,0x01,0x45,0x01,0x52,0x01, + 0x5f,0x01,0x6c,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xa0,0x01,0xad,0x01,0xba,0x01,0xc7,0x01, + 0xd4,0x01,0xe1,0x01,0xee,0x01,0xfb,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2f,0x02,0x3c,0x02, + 0x49,0x02,0x56,0x02,0x63,0x02,0x70,0x02,0x7d,0x02,0x8a,0x02,0x97,0x02,0xa4,0x02,0xb1,0x02, + 0xbe,0x02,0xcb,0x02,0xd8,0x02,0xe5,0x02,0xf2,0x02,0xff,0x02,0x0c,0x03,0x19,0x03,0x26,0x03, + 0x33,0x03,0x40,0x03,0x4d,0x03,0x5a,0x03,0x67,0x03,0x74,0x03,0x81,0x03,0x8e,0x03,0x9b,0x03, + 0xa8,0x03,0xb5,0x03,0xc2,0x03,0xcf,0x03,0xdc,0x03,0xe9,0x03,0xf6,0x03,0x03,0x04,0x10,0x04, + 0x1d,0x04,0x2a,0x04,0x37,0x04,0x44,0x04,0x51,0x04,0x5e,0x04,0x6b,0x04,0x78,0x04,0x85,0x04, + 0x92,0x04,0x9f,0x04,0xac,0x04,0xb9,0x04,0xc6,0x04,0xd3,0x04, + + 6, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 6, // 0x22 '"' + 0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x50,0x50,0xf8,0x50,0x50,0x50,0xf8,0x50,0x50,0x00,0x00, + + 6, // 0x24 '$' + 0x00,0x20,0x70,0xa8,0xa0,0x70,0x28,0xa8,0x70,0x20,0x00,0x00, + + 6, // 0x25 '%' + 0x00,0xc8,0xd8,0x10,0x30,0x20,0x60,0x40,0xd8,0x98,0x00,0x00, + + 6, // 0x26 '&' + 0x00,0x60,0x90,0x90,0x90,0x60,0xa8,0x90,0x90,0x68,0x00,0x00, + + 6, // 0x27 ''' + 0x00,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x00,0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10,0x00,0x00, + + 6, // 0x29 ')' + 0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00,0x00, + + 6, // 0x2a '*' + 0x00,0x00,0x00,0x50,0x20,0xf8,0x20,0x50,0x00,0x00,0x00,0x00, + + 6, // 0x2b '+' + 0x00,0x00,0x20,0x20,0x20,0xf8,0x20,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40, + + 6, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00, + + 6, // 0x2f '/' + 0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00, + + 6, // 0x30 '0' + 0x00,0x70,0x88,0x88,0x98,0xa8,0xc8,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x31 '1' + 0x00,0x20,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x32 '2' + 0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x40,0x80,0xf8,0x00,0x00, + + 6, // 0x33 '3' + 0x00,0xf8,0x10,0x20,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x10,0x20,0x40,0x90,0x90,0xf8,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x35 '5' + 0x00,0xf8,0x80,0x80,0xf0,0x08,0x08,0x08,0x88,0x70,0x00,0x00, + + 6, // 0x36 '6' + 0x00,0x70,0x88,0x80,0x80,0xf0,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0xf8,0x88,0x08,0x08,0x10,0x20,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x38 '8' + 0x00,0x70,0x88,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x39 '9' + 0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x08,0x88,0x70,0x00,0x00, + + 6, // 0x3a ':' + 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00, + + 6, // 0x3b ';' + 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x20,0x20,0x40, + + 6, // 0x3c '<' + 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00,0x00, + + 6, // 0x3d '=' + 0x00,0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3e '>' + 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00,0x00, + + 6, // 0x3f '?' + 0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00, + + 6, // 0x40 '@' + 0x00,0x70,0x88,0x88,0xb8,0xb8,0xb0,0x80,0x88,0x70,0x00,0x00, + + 6, // 0x41 'A' + 0x00,0x20,0x50,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x42 'B' + 0x00,0xf0,0x88,0x88,0x88,0xf0,0x88,0x88,0x88,0xf0,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x70,0x88,0x88,0x80,0x80,0x80,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x44 'D' + 0x00,0xe0,0x90,0x88,0x88,0x88,0x88,0x88,0x90,0xe0,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0xf8,0x80,0x80,0x80,0xf0,0x80,0x80,0x80,0xf8,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0xf8,0x80,0x80,0x80,0xf0,0x80,0x80,0x80,0x80,0x00,0x00, + + 6, // 0x47 'G' + 0x00,0x70,0x88,0x80,0x80,0xb8,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x48 'H' + 0x00,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x4a 'J' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00,0x00, + + 6, // 0x4b 'K' + 0x00,0x88,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x88,0x00,0x00, + + 6, // 0x4c 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x00,0x00, + + 6, // 0x4d 'M' + 0x00,0x88,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x4e 'N' + 0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x4f 'O' + 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x50 'P' + 0x00,0xf0,0x88,0x88,0x88,0xf0,0x80,0x80,0x80,0x80,0x00,0x00, + + 6, // 0x51 'Q' + 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0xa8,0x90,0x68,0x00,0x00, + + 6, // 0x52 'R' + 0x00,0xf0,0x88,0x88,0x88,0x88,0xf0,0xa0,0x90,0x88,0x00,0x00, + + 6, // 0x53 'S' + 0x00,0x70,0x88,0x80,0x80,0x70,0x08,0x08,0x88,0x70,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x55 'U' + 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x56 'V' + 0x00,0x88,0x88,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00,0x00, + + 6, // 0x57 'W' + 0x00,0x88,0x88,0x88,0x88,0x88,0xa8,0xa8,0xd8,0x88,0x00,0x00, + + 6, // 0x58 'X' + 0x00,0x88,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x59 'Y' + 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x5a 'Z' + 0x00,0xf8,0x08,0x08,0x10,0x20,0x40,0x80,0x80,0xf8,0x00,0x00, + + 6, // 0x5b '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, + + 6, // 0x5c '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00,0x00, + + 6, // 0x5d ']' + 0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, + + 6, // 0x5e '^' + 0x00,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x00, + + 6, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x70,0x88,0x08,0x78,0x88,0x88,0x78,0x00,0x00, + + 6, // 0x62 'b' + 0x00,0x80,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0xf0,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00,0x00, + + 6, // 0x64 'd' + 0x00,0x08,0x08,0x08,0x78,0x88,0x88,0x88,0x88,0x78,0x00,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x70,0x88,0x88,0xf8,0x80,0x80,0x78,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x18,0x20,0x20,0xf8,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x88,0x78,0x08,0x08,0xf0, + + 6, // 0x68 'h' + 0x00,0x80,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x69 'i' + 0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x6a 'j' + 0x00,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x90,0x60, + + 6, // 0x6b 'k' + 0x00,0x80,0x80,0x80,0x88,0x90,0xa0,0xd0,0x88,0x88,0x00,0x00, + + 6, // 0x6c 'l' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x6d 'm' + 0x00,0x00,0x00,0xd0,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0x00,0x00, + + 6, // 0x6e 'n' + 0x00,0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x6f 'o' + 0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0xf0,0x88,0x88,0x88,0x88,0xf0,0x80,0x80,0x80, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x88,0x78,0x08,0x08,0x08, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0xb0,0xc8,0x88,0x80,0x80,0x80,0x80,0x00,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x40,0x40,0x40,0xe0,0x40,0x40,0x40,0x48,0x30,0x00,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x78,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00,0x00, + + 6, // 0x77 'w' + 0x00,0x00,0x00,0x88,0x88,0x88,0xa8,0xa8,0xd8,0x88,0x00,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x88,0x78,0x08,0x10,0xe0, + + 6, // 0x7a 'z' + 0x00,0x00,0x00,0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x00,0x00, + + 6, // 0x7b '{' + 0x18,0x20,0x20,0x20,0x20,0xc0,0x20,0x20,0x20,0x20,0x18,0x00, + + 6, // 0x7c '|' + 0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x7d '}' + 0xc0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xc0,0x00, + + 6, // 0x7e '~' + 0x00,0x00,0x40,0xa8,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x7f '' + 0x00,0x00,0x00,0x00,0x20,0x50,0x88,0xf8,0x00,0x00,0x00,0x00, + 0 + }; + + const int8u gse6x9[] = + { + 9, 0, 32, 128-32, + + 0x00,0x00,0x0a,0x00,0x14,0x00,0x1e,0x00,0x28,0x00,0x32,0x00,0x3c,0x00,0x46,0x00,0x50,0x00, + 0x5a,0x00,0x64,0x00,0x6e,0x00,0x78,0x00,0x82,0x00,0x8c,0x00,0x96,0x00,0xa0,0x00,0xaa,0x00, + 0xb4,0x00,0xbe,0x00,0xc8,0x00,0xd2,0x00,0xdc,0x00,0xe6,0x00,0xf0,0x00,0xfa,0x00,0x04,0x01, + 0x0e,0x01,0x18,0x01,0x22,0x01,0x2c,0x01,0x36,0x01,0x40,0x01,0x4a,0x01,0x54,0x01,0x5e,0x01, + 0x68,0x01,0x72,0x01,0x7c,0x01,0x86,0x01,0x90,0x01,0x9a,0x01,0xa4,0x01,0xae,0x01,0xb8,0x01, + 0xc2,0x01,0xcc,0x01,0xd6,0x01,0xe0,0x01,0xea,0x01,0xf4,0x01,0xfe,0x01,0x08,0x02,0x12,0x02, + 0x1c,0x02,0x26,0x02,0x30,0x02,0x3a,0x02,0x44,0x02,0x4e,0x02,0x58,0x02,0x62,0x02,0x6c,0x02, + 0x76,0x02,0x80,0x02,0x8a,0x02,0x94,0x02,0x9e,0x02,0xa8,0x02,0xb2,0x02,0xbc,0x02,0xc6,0x02, + 0xd0,0x02,0xda,0x02,0xe4,0x02,0xee,0x02,0xf8,0x02,0x02,0x03,0x0c,0x03,0x16,0x03,0x20,0x03, + 0x2a,0x03,0x34,0x03,0x3e,0x03,0x48,0x03,0x52,0x03,0x5c,0x03,0x66,0x03,0x70,0x03,0x7a,0x03, + 0x84,0x03,0x8e,0x03,0x98,0x03,0xa2,0x03,0xac,0x03,0xb6,0x03, + + 6, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, + + 6, // 0x22 '"' + 0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x50,0x50,0xf8,0x50,0xf8,0x50,0x50,0x00, + + 6, // 0x24 '$' + 0x00,0x70,0xa8,0xa0,0x70,0x28,0xa8,0x70,0x00, + + 6, // 0x25 '%' + 0x00,0xc8,0xc8,0x10,0x20,0x40,0x98,0x98,0x00, + + 6, // 0x26 '&' + 0x00,0x60,0x90,0x90,0x60,0xa8,0x90,0x68,0x00, + + 6, // 0x27 ''' + 0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10, + + 6, // 0x29 ')' + 0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x40, + + 6, // 0x2a '*' + 0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00, + + 6, // 0x2b '+' + 0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x00,0x00, + + 6, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x40, + + 6, // 0x2d '-' + 0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00, + + 6, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, + + 6, // 0x2f '/' + 0x00,0x08,0x08,0x10,0x20,0x40,0x80,0x80,0x00, + + 6, // 0x30 '0' + 0x00,0x70,0x88,0x98,0xa8,0xc8,0x88,0x70,0x00, + + 6, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00, + + 6, // 0x32 '2' + 0x00,0x70,0x88,0x08,0x10,0x20,0x40,0xf8,0x00, + + 6, // 0x33 '3' + 0x00,0xf8,0x10,0x20,0x70,0x08,0x88,0x70,0x00, + + 6, // 0x34 '4' + 0x00,0x10,0x20,0x40,0x90,0xf8,0x10,0x10,0x00, + + 6, // 0x35 '5' + 0x00,0xf8,0x80,0xf0,0x08,0x08,0x88,0x70,0x00, + + 6, // 0x36 '6' + 0x00,0x70,0x88,0x80,0xf0,0x88,0x88,0x70,0x00, + + 6, // 0x37 '7' + 0x00,0xf8,0x08,0x08,0x10,0x20,0x40,0x40,0x00, + + 6, // 0x38 '8' + 0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00, + + 6, // 0x39 '9' + 0x00,0x70,0x88,0x88,0x78,0x08,0x88,0x70,0x00, + + 6, // 0x3a ':' + 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00, + + 6, // 0x3b ';' + 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x20,0x40, + + 6, // 0x3c '<' + 0x00,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00, + + 6, // 0x3d '=' + 0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00, + + 6, // 0x3e '>' + 0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0x00, + + 6, // 0x3f '?' + 0x00,0x70,0x88,0x08,0x10,0x20,0x00,0x20,0x00, + + 6, // 0x40 '@' + 0x00,0x70,0x88,0x88,0xb8,0xb8,0x80,0x70,0x00, + + 6, // 0x41 'A' + 0x00,0x20,0x50,0x88,0x88,0xf8,0x88,0x88,0x00, + + 6, // 0x42 'B' + 0x00,0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x00, + + 6, // 0x43 'C' + 0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00, + + 6, // 0x44 'D' + 0x00,0xe0,0x90,0x88,0x88,0x88,0x90,0xe0,0x00, + + 6, // 0x45 'E' + 0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8,0x00, + + 6, // 0x46 'F' + 0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0x80,0x00, + + 6, // 0x47 'G' + 0x00,0x70,0x88,0x80,0xb8,0x88,0x88,0x70,0x00, + + 6, // 0x48 'H' + 0x00,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x00, + + 6, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 6, // 0x4a 'J' + 0x00,0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00, + + 6, // 0x4b 'K' + 0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x00, + + 6, // 0x4c 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x00, + + 6, // 0x4d 'M' + 0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x00, + + 6, // 0x4e 'N' + 0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88,0x00, + + 6, // 0x4f 'O' + 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00, + + 6, // 0x50 'P' + 0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x80,0x00, + + 6, // 0x51 'Q' + 0x00,0x70,0x88,0x88,0x88,0xa8,0x90,0x68,0x00, + + 6, // 0x52 'R' + 0x00,0xf0,0x88,0x88,0x88,0xf0,0x90,0x88,0x00, + + 6, // 0x53 'S' + 0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00, + + 6, // 0x54 'T' + 0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 6, // 0x55 'U' + 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00, + + 6, // 0x56 'V' + 0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00, + + 6, // 0x57 'W' + 0x00,0x88,0x88,0x88,0xa8,0xa8,0xd8,0x88,0x00, + + 6, // 0x58 'X' + 0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00, + + 6, // 0x59 'Y' + 0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00, + + 6, // 0x5a 'Z' + 0x00,0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x00, + + 6, // 0x5b '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70, + + 6, // 0x5c '\' + 0x00,0x80,0x80,0x40,0x20,0x10,0x08,0x08,0x00, + + 6, // 0x5d ']' + 0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70, + + 6, // 0x5e '^' + 0x00,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00, + + 6, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00, + + 6, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00, + + 6, // 0x62 'b' + 0x00,0x80,0x80,0xf0,0x88,0x88,0x88,0xf0,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x00, + + 6, // 0x64 'd' + 0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x70,0x88,0xf8,0x80,0x78,0x00, + + 6, // 0x66 'f' + 0x00,0x18,0x20,0x20,0xf8,0x20,0x20,0x20,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x70, + + 6, // 0x68 'h' + 0x00,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x00, + + 6, // 0x69 'i' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00, + + 6, // 0x6a 'j' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x90,0x60, + + 6, // 0x6b 'k' + 0x00,0x00,0x80,0x88,0x90,0xa0,0xd0,0x88,0x00, + + 6, // 0x6c 'l' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 6, // 0x6d 'm' + 0x00,0x00,0x00,0xd0,0xa8,0xa8,0xa8,0xa8,0x00, + + 6, // 0x6e 'n' + 0x00,0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x00, + + 6, // 0x6f 'o' + 0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0xf0,0x88,0x88,0xf0,0x80,0x80, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x08, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0xb8,0xc0,0x80,0x80,0x80,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x78,0x80,0x70,0x08,0xf0,0x00, + + 6, // 0x74 't' + 0x00,0x40,0x40,0xe0,0x40,0x40,0x48,0x30,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x78,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00, + + 6, // 0x77 'w' + 0x00,0x00,0x00,0x88,0x88,0xa8,0xd8,0x88,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x70, + + 6, // 0x7a 'z' + 0x00,0x00,0x00,0xf8,0x10,0x20,0x40,0xf8,0x00, + + 6, // 0x7b '{' + 0x18,0x20,0x20,0x20,0xc0,0x20,0x20,0x20,0x18, + + 6, // 0x7c '|' + 0x00,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00, + + 6, // 0x7d '}' + 0xc0,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0xc0, + + 6, // 0x7e '~' + 0x00,0x40,0xa8,0x10,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x7f '' + 0x00,0x00,0x00,0x20,0x50,0x88,0xf8,0x00,0x00, + 0 + }; + + const int8u gse7x11[] = + { + 11, 0, 32, 128-32, + + 0x00,0x00,0x0c,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3c,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6c,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9c,0x00,0xa8,0x00,0xb4,0x00,0xc0,0x00,0xcc,0x00, + 0xd8,0x00,0xe4,0x00,0xf0,0x00,0xfc,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2c,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5c,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8c,0x01,0x98,0x01,0xa4,0x01, + 0xb0,0x01,0xbc,0x01,0xc8,0x01,0xd4,0x01,0xe0,0x01,0xec,0x01,0xf8,0x01,0x04,0x02,0x10,0x02, + 0x1c,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4c,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7c,0x02, + 0x88,0x02,0x94,0x02,0xa0,0x02,0xac,0x02,0xb8,0x02,0xc4,0x02,0xd0,0x02,0xdc,0x02,0xe8,0x02, + 0xf4,0x02,0x00,0x03,0x0c,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3c,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6c,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9c,0x03,0xa8,0x03,0xb4,0x03,0xc0,0x03, + 0xcc,0x03,0xd8,0x03,0xe4,0x03,0xf0,0x03,0xfc,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2c,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5c,0x04,0x68,0x04,0x74,0x04, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x00,0x10,0x38,0x38,0x38,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00, + + 7, // 0x25 '%' + 0x00,0x00,0x42,0xa4,0x48,0x10,0x24,0x4a,0x84,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x30,0x48,0x48,0x30,0x60,0x94,0x98,0x6c,0x00,0x00, + + 7, // 0x27 ''' + 0x00,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x04,0x08,0x10,0x10,0x10,0x10,0x08,0x04,0x00,0x00, + + 7, // 0x29 ')' + 0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x20,0x40,0x00,0x00, + + 7, // 0x2a '*' + 0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00, + + 7, // 0x2b '+' + 0x00,0x00,0x00,0x10,0x10,0x7c,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60, + + 7, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 7, // 0x2f '/' + 0x00,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x38,0x44,0x4c,0x54,0x64,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x7c,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x38,0x44,0x04,0x08,0x10,0x20,0x44,0x7c,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x7c,0x48,0x10,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x08,0x10,0x20,0x48,0x48,0x7c,0x08,0x1c,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x7c,0x40,0x40,0x78,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x18,0x20,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x7c,0x44,0x04,0x08,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3c,0x04,0x08,0x30,0x00,0x00, + + 7, // 0x3a ':' + 0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00, + + 7, // 0x3b ';' + 0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x30,0x60,0x00, + + 7, // 0x3c '<' + 0x00,0x00,0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x00,0x00, + + 7, // 0x3d '=' + 0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00, + + 7, // 0x3e '>' + 0x00,0x00,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,0x00, + + 7, // 0x3f '?' + 0x00,0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x30,0x48,0x04,0x34,0x54,0x54,0x54,0x28,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x10,0x28,0x44,0x44,0x7c,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x7c,0x40,0x40,0x70,0x40,0x40,0x40,0x7c,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x7c,0x40,0x40,0x70,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5c,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x4a 'J' + 0x00,0x1c,0x08,0x08,0x08,0x08,0x08,0x48,0x30,0x00,0x00, + + 7, // 0x4b 'K' + 0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x44,0x00,0x00, + + 7, // 0x4c 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7c,0x00,0x00, + + 7, // 0x4d 'M' + 0x00,0x44,0x6c,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x4e 'N' + 0x00,0x44,0x44,0x64,0x54,0x4c,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x4f 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x78,0x50,0x48,0x44,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x7c,0x54,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0x44,0x44,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x5a 'Z' + 0x00,0x7c,0x04,0x08,0x10,0x20,0x40,0x44,0x7c,0x00,0x00, + + 7, // 0x5b '[' + 0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00,0x00, + + 7, // 0x5c '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00,0x00, + + 7, // 0x5d ']' + 0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00,0x00, + + 7, // 0x5e '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3c,0x44,0x44,0x3c,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x04,0x04,0x3c,0x44,0x44,0x44,0x44,0x3c,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x7c,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x18,0x24,0x20,0x70,0x20,0x20,0x20,0x70,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x3c,0x44,0x44,0x44,0x3c,0x04,0x44,0x38, + + 7, // 0x68 'h' + 0x00,0x40,0x40,0x40,0x58,0x64,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x6a 'j' + 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x48,0x30,0x00, + + 7, // 0x6b 'k' + 0x00,0x40,0x40,0x44,0x48,0x50,0x68,0x44,0x44,0x00,0x00, + + 7, // 0x6c 'l' + 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x6d 'm' + 0x00,0x00,0x00,0xa8,0x54,0x54,0x54,0x54,0x54,0x00,0x00, + + 7, // 0x6e 'n' + 0x00,0x00,0x00,0xb8,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x6f 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x3c,0x44,0x44,0x44,0x44,0x3c,0x04,0x04, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x64,0x44,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x3c,0x40,0x38,0x04,0x04,0x78,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x24,0x18,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3a,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x3c,0x04,0x08,0x30,0x00, + + 7, // 0x7a 'z' + 0x00,0x00,0x00,0x7c,0x08,0x10,0x20,0x44,0x7c,0x00,0x00, + + 7, // 0x7b '{' + 0x00,0x0c,0x10,0x10,0x10,0x60,0x10,0x10,0x0c,0x00,0x00, + + 7, // 0x7c '|' + 0x00,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00,0x00, + + 7, // 0x7d '}' + 0x00,0x60,0x10,0x10,0x10,0x0c,0x10,0x10,0x60,0x00,0x00, + + 7, // 0x7e '~' + 0x00,0x00,0x64,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7f '' + 0x00,0x00,0x00,0x10,0x28,0x44,0x44,0x7c,0x00,0x00,0x00, + 0 + }; + + const int8u gse7x11_bold[] = + { + 11, 0, 32, 128-32, + + 0x00,0x00,0x0c,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3c,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6c,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9c,0x00,0xa8,0x00,0xb4,0x00,0xc0,0x00,0xcc,0x00, + 0xd8,0x00,0xe4,0x00,0xf0,0x00,0xfc,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2c,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5c,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8c,0x01,0x98,0x01,0xa4,0x01, + 0xb0,0x01,0xbc,0x01,0xc8,0x01,0xd4,0x01,0xe0,0x01,0xec,0x01,0xf8,0x01,0x04,0x02,0x10,0x02, + 0x1c,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4c,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7c,0x02, + 0x88,0x02,0x94,0x02,0xa0,0x02,0xac,0x02,0xb8,0x02,0xc4,0x02,0xd0,0x02,0xdc,0x02,0xe8,0x02, + 0xf4,0x02,0x00,0x03,0x0c,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3c,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6c,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9c,0x03,0xa8,0x03,0xb4,0x03,0xc0,0x03, + 0xcc,0x03,0xd8,0x03,0xe4,0x03,0xf0,0x03,0xfc,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2c,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5c,0x04,0x68,0x04,0x74,0x04, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x00,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x6c,0x6c,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x00,0x00, + + 7, // 0x24 '$' + 0x30,0x30,0x78,0xcc,0xc0,0x78,0x0c,0xcc,0x78,0x30,0x30, + + 7, // 0x25 '%' + 0x00,0x00,0xc4,0x0c,0x18,0x30,0x60,0xc0,0x8c,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x30,0x58,0x58,0x30,0x74,0xdc,0xd8,0x6c,0x00,0x00, + + 7, // 0x27 ''' + 0x00,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00, + + 7, // 0x29 ')' + 0x00,0xc0,0x60,0x30,0x30,0x30,0x30,0x60,0xc0,0x00,0x00, + + 7, // 0x2a '*' + 0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00, + + 7, // 0x2b '+' + 0x00,0x00,0x00,0x30,0x30,0xfc,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00, + + 7, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 7, // 0x2f '/' + 0x00,0x0c,0x0c,0x18,0x18,0x30,0x30,0x60,0x60,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x78,0xcc,0xcc,0xdc,0xec,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x30,0x70,0xf0,0x30,0x30,0x30,0x30,0xfc,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x78,0xcc,0xcc,0x18,0x30,0x60,0xcc,0xfc,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0xfc,0x98,0x30,0x78,0x0c,0x0c,0xcc,0x78,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x18,0x30,0x68,0xd8,0xd8,0xfc,0x18,0x3c,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0xfc,0xc0,0xc0,0xf8,0x0c,0x0c,0xcc,0x78,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x38,0x60,0xc0,0xf8,0xcc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0xfc,0x8c,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x78,0xcc,0xcc,0x78,0xcc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x78,0xcc,0xcc,0xcc,0x7c,0x0c,0x18,0x70,0x00,0x00, + + 7, // 0x3a ':' + 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x3b ';' + 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x60,0x00, + + 7, // 0x3c '<' + 0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x00, + + 7, // 0x3d '=' + 0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00, + + 7, // 0x3e '>' + 0x00,0x00,0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0x00,0x00, + + 7, // 0x3f '?' + 0x00,0x78,0xcc,0xcc,0x18,0x30,0x30,0x00,0x30,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x70,0x88,0x04,0x74,0xb4,0xb4,0xb4,0x68,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x30,0x78,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0xf8,0xcc,0xcc,0xf8,0xcc,0xcc,0xcc,0xf8,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x78,0xcc,0xc0,0xc0,0xc0,0xc0,0xcc,0x78,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0xf0,0xd8,0xcc,0xcc,0xcc,0xcc,0xd8,0xf0,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0xfc,0xc4,0xd0,0xf0,0xd0,0xc0,0xc4,0xfc,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0xfc,0xc4,0xd0,0xf0,0xd0,0xc0,0xc0,0xc0,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x78,0xcc,0xc0,0xc0,0xdc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x4a 'J' + 0x00,0x3c,0x18,0x18,0x18,0x18,0xd8,0xd8,0x70,0x00,0x00, + + 7, // 0x4b 'K' + 0x00,0xcc,0xcc,0xd8,0xf0,0xd8,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x4c 'L' + 0x00,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc4,0xfc,0x00,0x00, + + 7, // 0x4d 'M' + 0x00,0x84,0xcc,0xfc,0xb4,0xcc,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x4e 'N' + 0x00,0xcc,0xcc,0xec,0xfc,0xdc,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x4f 'O' + 0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xdc,0x78,0x18,0x0c,0x00, + + 7, // 0x52 'R' + 0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xd8,0xcc,0xcc,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x78,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0x78,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0xfc,0xb4,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0xcc,0xcc,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0xcc,0xcc,0x78,0x30,0x78,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0xcc,0xcc,0xcc,0x78,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x5a 'Z' + 0x00,0xfc,0x8c,0x18,0x30,0x60,0xc0,0xc4,0xfc,0x00,0x00, + + 7, // 0x5b '[' + 0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x78,0x00,0x00, + + 7, // 0x5c '\' + 0x00,0x60,0x60,0x30,0x30,0x18,0x18,0x0c,0x0c,0x00,0x00, + + 7, // 0x5d ']' + 0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x00,0x00, + + 7, // 0x5e '^' + 0x00,0x10,0x38,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x70,0x18,0x78,0xd8,0xd8,0x6c,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x60,0x60,0x60,0x78,0x6c,0x6c,0x6c,0x78,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x78,0xcc,0xc0,0xc0,0xcc,0x78,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x18,0x18,0x18,0x78,0xd8,0xd8,0xd8,0x6c,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x78,0xcc,0xfc,0xc0,0xcc,0x78,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x18,0x34,0x30,0x78,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x6c,0xd8,0xd8,0xd8,0x78,0x18,0xd8,0x70, + + 7, // 0x68 'h' + 0x00,0xc0,0xc0,0xd8,0xec,0xcc,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x6a 'j' + 0x00,0x0c,0x00,0x1c,0x0c,0x0c,0x0c,0x0c,0x6c,0x6c,0x38, + + 7, // 0x6b 'k' + 0x00,0xc0,0xc0,0xcc,0xcc,0xd8,0xf0,0xd8,0xcc,0x00,0x00, + + 7, // 0x6c 'l' + 0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x6d 'm' + 0x00,0x00,0x00,0xe8,0xfc,0xd4,0xd4,0xc4,0xc4,0x00,0x00, + + 7, // 0x6e 'n' + 0x00,0x00,0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00, + + 7, // 0x6f 'o' + 0x00,0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x7c,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x0c, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0xd8,0xec,0xcc,0xc0,0xc0,0xc0,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x78,0xcc,0x60,0x18,0xcc,0x78,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x20,0x60,0x60,0xf0,0x60,0x60,0x68,0x30,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0xd8,0xd8,0xd8,0xd8,0xd8,0x6c,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0xcc,0x78,0x30,0x78,0xcc,0xcc,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x18,0xf0, + + 7, // 0x7a 'z' + 0x00,0x00,0x00,0xfc,0x98,0x30,0x60,0xc4,0xfc,0x00,0x00, + + 7, // 0x7b '{' + 0x1c,0x30,0x30,0x30,0xe0,0x30,0x30,0x30,0x1c,0x00,0x00, + + 7, // 0x7c '|' + 0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x30,0x30,0x00,0x00, + + 7, // 0x7d '}' + 0xe0,0x30,0x30,0x30,0x1c,0x30,0x30,0x30,0xe0,0x00,0x00, + + 7, // 0x7e '~' + 0x00,0x34,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7f '' + 0x00,0x00,0x00,0x30,0x78,0xcc,0xcc,0xfc,0x00,0x00,0x00, + 0 + }; + + const int8u gse7x15[] = + { + 15, 0, 32, 128-32, + + 0x00,0x00,0x10,0x00,0x20,0x00,0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,0x70,0x00,0x80,0x00, + 0x90,0x00,0xa0,0x00,0xb0,0x00,0xc0,0x00,0xd0,0x00,0xe0,0x00,0xf0,0x00,0x00,0x01,0x10,0x01, + 0x20,0x01,0x30,0x01,0x40,0x01,0x50,0x01,0x60,0x01,0x70,0x01,0x80,0x01,0x90,0x01,0xa0,0x01, + 0xb0,0x01,0xc0,0x01,0xd0,0x01,0xe0,0x01,0xf0,0x01,0x00,0x02,0x10,0x02,0x20,0x02,0x30,0x02, + 0x40,0x02,0x50,0x02,0x60,0x02,0x70,0x02,0x80,0x02,0x90,0x02,0xa0,0x02,0xb0,0x02,0xc0,0x02, + 0xd0,0x02,0xe0,0x02,0xf0,0x02,0x00,0x03,0x10,0x03,0x20,0x03,0x30,0x03,0x40,0x03,0x50,0x03, + 0x60,0x03,0x70,0x03,0x80,0x03,0x90,0x03,0xa0,0x03,0xb0,0x03,0xc0,0x03,0xd0,0x03,0xe0,0x03, + 0xf0,0x03,0x00,0x04,0x10,0x04,0x20,0x04,0x30,0x04,0x40,0x04,0x50,0x04,0x60,0x04,0x70,0x04, + 0x80,0x04,0x90,0x04,0xa0,0x04,0xb0,0x04,0xc0,0x04,0xd0,0x04,0xe0,0x04,0xf0,0x04,0x00,0x05, + 0x10,0x05,0x20,0x05,0x30,0x05,0x40,0x05,0x50,0x05,0x60,0x05,0x70,0x05,0x80,0x05,0x90,0x05, + 0xa0,0x05,0xb0,0x05,0xc0,0x05,0xd0,0x05,0xe0,0x05,0xf0,0x05, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x00,0x00,0x10,0x38,0x38,0x38,0x38,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x00,0x48,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x48,0x00,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x54,0x38,0x10,0x00,0x00,0x00, + + 7, // 0x25 '%' + 0x00,0x00,0x44,0x44,0x08,0x08,0x10,0x10,0x20,0x20,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x00,0x00,0x30,0x48,0x48,0x30,0x60,0x94,0x98,0x90,0x6c,0x00,0x00,0x00, + + 7, // 0x27 ''' + 0x00,0x00,0x20,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x04,0x08,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x08,0x04,0x00,0x00,0x00, + + 7, // 0x29 ')' + 0x00,0x40,0x20,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x20,0x40,0x00,0x00,0x00, + + 7, // 0x2a '*' + 0x00,0x00,0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2b '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x7c,0x10,0x10,0x10,0x00,0x00,0x00,0x00, + + 7, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x00, + + 7, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x2f '/' + 0x00,0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x00,0x38,0x44,0x44,0x4c,0x54,0x64,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x00,0x10,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x7c,0x00,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x00,0x38,0x44,0x44,0x04,0x08,0x10,0x20,0x40,0x44,0x7c,0x00,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x00,0x7c,0x44,0x08,0x10,0x38,0x04,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x00,0x08,0x10,0x20,0x40,0x48,0x48,0x7c,0x08,0x08,0x1c,0x00,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x00,0x7c,0x40,0x40,0x40,0x78,0x04,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x00,0x18,0x20,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x00,0x7c,0x44,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x3c,0x04,0x04,0x08,0x30,0x00,0x00,0x00, + + 7, // 0x3a ':' + 0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00, + + 7, // 0x3b ';' + 0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00, + + 7, // 0x3c '<' + 0x00,0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00,0x00, + + 7, // 0x3d '=' + 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3e '>' + 0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00,0x00, + + 7, // 0x3f '?' + 0x00,0x00,0x78,0x84,0x84,0x84,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x00,0x00,0x30,0x48,0x04,0x34,0x54,0x54,0x54,0x54,0x28,0x00,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x00,0x10,0x28,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x00,0x38,0x44,0x44,0x40,0x40,0x40,0x40,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x00,0x7c,0x40,0x40,0x40,0x70,0x40,0x40,0x40,0x40,0x7c,0x00,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x00,0x7c,0x40,0x40,0x40,0x70,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x5c,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x00,0x44,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x4a 'J' + 0x00,0x00,0x1c,0x08,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00,0x00, + + 7, // 0x4b 'K' + 0x00,0x00,0x44,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x4c 'L' + 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7c,0x00,0x00,0x00, + + 7, // 0x4d 'M' + 0x00,0x00,0x44,0x6c,0x54,0x54,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x4e 'N' + 0x00,0x00,0x44,0x44,0x44,0x64,0x54,0x4c,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x4f 'O' + 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x50,0x48,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x00,0x38,0x44,0x44,0x40,0x38,0x04,0x04,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x00,0x7c,0x54,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x5a 'Z' + 0x00,0x00,0x7c,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x40,0x7c,0x00,0x00,0x00, + + 7, // 0x5b '[' + 0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00,0x00, + + 7, // 0x5c '\' + 0x00,0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00,0x00,0x00, + + 7, // 0x5d ']' + 0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00,0x00, + + 7, // 0x5e '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x20,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x3c,0x44,0x44,0x44,0x3a,0x00,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x00,0x04,0x04,0x04,0x3c,0x44,0x44,0x44,0x44,0x44,0x3a,0x00,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x7c,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x00,0x18,0x24,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x3a,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x44,0x38,0x00, + + 7, // 0x68 'h' + 0x00,0x00,0x40,0x40,0x40,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x00,0x10,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x6a 'j' + 0x00,0x00,0x08,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00, + + 7, // 0x6b 'k' + 0x00,0x00,0x40,0x40,0x44,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, + + 7, // 0x6c 'l' + 0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x6d 'm' + 0x00,0x00,0x00,0x00,0xa8,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x00,0x00,0x00, + + 7, // 0x6e 'n' + 0x00,0x00,0x00,0x00,0xb8,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x6f 'o' + 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x3c,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x04,0x04,0x00, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x58,0x64,0x44,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x00,0x20,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x24,0x18,0x00,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x3a,0x00,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x08,0x70,0x00, + + 7, // 0x7a 'z' + 0x00,0x00,0x00,0x00,0x7c,0x04,0x08,0x10,0x20,0x40,0x40,0x7c,0x00,0x00,0x00, + + 7, // 0x7b '{' + 0x00,0x0c,0x10,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x0c,0x00,0x00, + + 7, // 0x7c '|' + 0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 7, // 0x7d '}' + 0x00,0x60,0x10,0x10,0x10,0x10,0x10,0x0c,0x10,0x10,0x10,0x10,0x60,0x00,0x00, + + 7, // 0x7e '~' + 0x00,0x00,0x64,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7f '' + 0x00,0x00,0x00,0x00,0x00,0x10,0x28,0x44,0x44,0x7c,0x00,0x00,0x00,0x00,0x00, + 0 + }; + + const int8u gse7x15_bold[] = + { + 15, 0, 32, 128-32, + + 0x00,0x00,0x10,0x00,0x20,0x00,0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,0x70,0x00,0x80,0x00, + 0x90,0x00,0xa0,0x00,0xb0,0x00,0xc0,0x00,0xd0,0x00,0xe0,0x00,0xf0,0x00,0x00,0x01,0x10,0x01, + 0x20,0x01,0x30,0x01,0x40,0x01,0x50,0x01,0x60,0x01,0x70,0x01,0x80,0x01,0x90,0x01,0xa0,0x01, + 0xb0,0x01,0xc0,0x01,0xd0,0x01,0xe0,0x01,0xf0,0x01,0x00,0x02,0x10,0x02,0x20,0x02,0x30,0x02, + 0x40,0x02,0x50,0x02,0x60,0x02,0x70,0x02,0x80,0x02,0x90,0x02,0xa0,0x02,0xb0,0x02,0xc0,0x02, + 0xd0,0x02,0xe0,0x02,0xf0,0x02,0x00,0x03,0x10,0x03,0x20,0x03,0x30,0x03,0x40,0x03,0x50,0x03, + 0x60,0x03,0x70,0x03,0x80,0x03,0x90,0x03,0xa0,0x03,0xb0,0x03,0xc0,0x03,0xd0,0x03,0xe0,0x03, + 0xf0,0x03,0x00,0x04,0x10,0x04,0x20,0x04,0x30,0x04,0x40,0x04,0x50,0x04,0x60,0x04,0x70,0x04, + 0x80,0x04,0x90,0x04,0xa0,0x04,0xb0,0x04,0xc0,0x04,0xd0,0x04,0xe0,0x04,0xf0,0x04,0x00,0x05, + 0x10,0x05,0x20,0x05,0x30,0x05,0x40,0x05,0x50,0x05,0x60,0x05,0x70,0x05,0x80,0x05,0x90,0x05, + 0xa0,0x05,0xb0,0x05,0xc0,0x05,0xd0,0x05,0xe0,0x05,0xf0,0x05, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x00,0x00,0x00,0x30,0x78,0x78,0x78,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x6c,0x6c,0x6c,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x00,0x48,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x48,0x00,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x30,0x30,0x78,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0x78,0x30,0x30,0x00,0x00, + + 7, // 0x25 '%' + 0x00,0x00,0x00,0x64,0x6c,0x08,0x18,0x10,0x30,0x20,0x6c,0x4c,0x00,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x00,0x00,0x30,0x58,0x58,0x30,0x74,0xdc,0xd8,0xd8,0x6c,0x00,0x00,0x00, + + 7, // 0x27 ''' + 0x00,0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x0c,0x18,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x18,0x0c,0x00,0x00,0x00, + + 7, // 0x29 ')' + 0x00,0xc0,0x60,0x30,0x18,0x18,0x18,0x18,0x18,0x30,0x60,0xc0,0x00,0x00,0x00, + + 7, // 0x2a '*' + 0x00,0x00,0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2b '+' + 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0xfc,0x30,0x30,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x00, + + 7, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x2f '/' + 0x00,0x00,0x0c,0x0c,0x18,0x18,0x30,0x30,0x60,0x60,0xc0,0xc0,0x00,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xdc,0xec,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x00,0x30,0x30,0x70,0xf0,0x30,0x30,0x30,0x30,0x30,0xfc,0x00,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x00,0x78,0xcc,0xcc,0x0c,0x18,0x30,0x60,0xc0,0xcc,0xfc,0x00,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x00,0xfc,0x8c,0x18,0x30,0x78,0x0c,0x0c,0x0c,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x00,0x18,0x30,0x60,0xc8,0xd8,0xd8,0xfc,0x18,0x18,0x3c,0x00,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x00,0xfc,0xc0,0xc0,0xc0,0xf8,0x0c,0x0c,0x0c,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x00,0x38,0x60,0xc0,0xc0,0xf8,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x00,0xfc,0x8c,0x0c,0x0c,0x18,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x18,0x70,0x00,0x00,0x00, + + 7, // 0x3a ':' + 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00, + + 7, // 0x3b ';' + 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x00, + + 7, // 0x3c '<' + 0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0xc0,0x60,0x30,0x18,0x0c,0x00,0x00,0x00, + + 7, // 0x3d '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3e '>' + 0x00,0x00,0x00,0xc0,0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0xc0,0x00,0x00,0x00, + + 7, // 0x3f '?' + 0x00,0x00,0x78,0xcc,0xcc,0x18,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x00,0x00,0x70,0x88,0x04,0x74,0xb4,0xb4,0xb4,0xb4,0x68,0x00,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x00,0x30,0x78,0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xcc,0xcc,0xcc,0xcc,0xf8,0x00,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x00,0x78,0xcc,0xc4,0xc0,0xc0,0xc0,0xc0,0xc4,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x00,0xf0,0xd8,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xd8,0xf0,0x00,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x00,0xfc,0xc4,0xc0,0xd0,0xf0,0xd0,0xc0,0xc0,0xc4,0xfc,0x00,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x00,0xfc,0xc4,0xc0,0xd0,0xf0,0xd0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x00,0x78,0xcc,0xc0,0xc0,0xc0,0xdc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, + + 7, // 0x4a 'J' + 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0x70,0x00,0x00,0x00, + + 7, // 0x4b 'K' + 0x00,0x00,0xcc,0xcc,0xd8,0xd8,0xf0,0xd8,0xd8,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x4c 'L' + 0x00,0x00,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc4,0xfc,0x00,0x00,0x00, + + 7, // 0x4d 'M' + 0x00,0x00,0x84,0xcc,0xfc,0xb4,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x4e 'N' + 0x00,0x00,0xcc,0xcc,0xcc,0xec,0xfc,0xdc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x4f 'O' + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xdc,0x78,0x18,0x0c,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xcc,0xf8,0xd8,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x00,0x78,0xcc,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x00,0xfc,0xb4,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x00,0xcc,0xcc,0xcc,0x78,0x30,0x78,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, + + 7, // 0x5a 'Z' + 0x00,0x00,0xfc,0x8c,0x0c,0x18,0x30,0x60,0xc0,0xc0,0xc4,0xfc,0x00,0x00,0x00, + + 7, // 0x5b '[' + 0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78,0x00,0x00, + + 7, // 0x5c '\' + 0x00,0x00,0xc0,0xc0,0x60,0x60,0x30,0x30,0x18,0x18,0x0c,0x0c,0x00,0x00,0x00, + + 7, // 0x5d ']' + 0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x00,0x00, + + 7, // 0x5e '^' + 0x00,0x10,0x38,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x30,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x70,0xd8,0x18,0x78,0xd8,0xd8,0xd8,0x6c,0x00,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x00,0x60,0x60,0x60,0x78,0x6c,0x6c,0x6c,0x6c,0x6c,0x78,0x00,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x78,0xcc,0xc0,0xc0,0xc0,0xc0,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x00,0x18,0x18,0x18,0x78,0xd8,0xd8,0xd8,0xd8,0xd8,0x6c,0x00,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x78,0xcc,0xcc,0xfc,0xc0,0xc0,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x00,0x30,0x68,0x60,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x6c,0xd8,0xd8,0xd8,0xd8,0xd8,0x78,0x18,0xd8,0x70,0x00, + + 7, // 0x68 'h' + 0x00,0x00,0xc0,0xc0,0xc0,0xd8,0xec,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x00,0x30,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, + + 7, // 0x6a 'j' + 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0x70,0x00, + + 7, // 0x6b 'k' + 0x00,0x00,0xc0,0xc0,0xcc,0xcc,0xcc,0xd8,0xf0,0xd8,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x6c 'l' + 0x00,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, + + 7, // 0x6d 'm' + 0x00,0x00,0x00,0x00,0xe8,0xfc,0xd4,0xd4,0xd4,0xc4,0xc4,0xc4,0x00,0x00,0x00, + + 7, // 0x6e 'n' + 0x00,0x00,0x00,0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00, + + 7, // 0x6f 'o' + 0x00,0x00,0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0,0x00, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x7c,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x0c,0x00, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x00,0xd8,0xec,0xcc,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x78,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x00,0x20,0x60,0x60,0xf0,0x60,0x60,0x60,0x60,0x6c,0x38,0x00,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x00,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0x6c,0x00,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x00,0xcc,0xcc,0x78,0x30,0x78,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x18,0xf0,0x00, + + 7, // 0x7a 'z' + 0x00,0x00,0x00,0x00,0xfc,0x8c,0x18,0x30,0x60,0xc0,0xc4,0xfc,0x00,0x00,0x00, + + 7, // 0x7b '{' + 0x00,0x1c,0x30,0x30,0x30,0x30,0x30,0xe0,0x30,0x30,0x30,0x30,0x1c,0x00,0x00, + + 7, // 0x7c '|' + 0x00,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x00,0x00, + + 7, // 0x7d '}' + 0x00,0xe0,0x30,0x30,0x30,0x30,0x30,0x1c,0x30,0x30,0x30,0x30,0xe0,0x00,0x00, + + 7, // 0x7e '~' + 0x00,0x00,0x34,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7f '' + 0x00,0x00,0x00,0x00,0x00,0x30,0x78,0xcc,0xcc,0xfc,0x00,0x00,0x00,0x00,0x00, + 0 + }; + + const int8u gse8x16[] = + { + 16, 0, 32, 128-32, + + 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x44,0x00,0x55,0x00,0x66,0x00,0x77,0x00,0x88,0x00, + 0x99,0x00,0xaa,0x00,0xbb,0x00,0xcc,0x00,0xdd,0x00,0xee,0x00,0xff,0x00,0x10,0x01,0x21,0x01, + 0x32,0x01,0x43,0x01,0x54,0x01,0x65,0x01,0x76,0x01,0x87,0x01,0x98,0x01,0xa9,0x01,0xba,0x01, + 0xcb,0x01,0xdc,0x01,0xed,0x01,0xfe,0x01,0x0f,0x02,0x20,0x02,0x31,0x02,0x42,0x02,0x53,0x02, + 0x64,0x02,0x75,0x02,0x86,0x02,0x97,0x02,0xa8,0x02,0xb9,0x02,0xca,0x02,0xdb,0x02,0xec,0x02, + 0xfd,0x02,0x0e,0x03,0x1f,0x03,0x30,0x03,0x41,0x03,0x52,0x03,0x63,0x03,0x74,0x03,0x85,0x03, + 0x96,0x03,0xa7,0x03,0xb8,0x03,0xc9,0x03,0xda,0x03,0xeb,0x03,0xfc,0x03,0x0d,0x04,0x1e,0x04, + 0x2f,0x04,0x40,0x04,0x51,0x04,0x62,0x04,0x73,0x04,0x84,0x04,0x95,0x04,0xa6,0x04,0xb7,0x04, + 0xc8,0x04,0xd9,0x04,0xea,0x04,0xfb,0x04,0x0c,0x05,0x1d,0x05,0x2e,0x05,0x3f,0x05,0x50,0x05, + 0x61,0x05,0x72,0x05,0x83,0x05,0x94,0x05,0xa5,0x05,0xb6,0x05,0xc7,0x05,0xd8,0x05,0xe9,0x05, + 0xfa,0x05,0x0b,0x06,0x1c,0x06,0x2d,0x06,0x3e,0x06,0x4f,0x06, + + 8, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x21 '!' + 0x00,0x00,0x10,0x38,0x38,0x38,0x38,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00,0x00, + + 8, // 0x22 '"' + 0x00,0x24,0x24,0x24,0x24,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x23 '#' + 0x00,0x00,0x24,0x24,0x24,0x7e,0x24,0x24,0x7e,0x24,0x24,0x24,0x00,0x00,0x00,0x00, + + 8, // 0x24 '$' + 0x00,0x14,0x14,0x3e,0x55,0x54,0x54,0x3e,0x15,0x15,0x55,0x3e,0x14,0x14,0x00,0x00, + + 8, // 0x25 '%' + 0x00,0x00,0x32,0x56,0x6c,0x04,0x08,0x08,0x10,0x13,0x25,0x26,0x00,0x00,0x00,0x00, + + 8, // 0x26 '&' + 0x00,0x00,0x18,0x24,0x24,0x24,0x18,0x28,0x45,0x46,0x44,0x3b,0x00,0x00,0x00,0x00, + + 8, // 0x27 ''' + 0x00,0x00,0x08,0x08,0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x28 '(' + 0x00,0x04,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x04,0x00,0x00,0x00, + + 8, // 0x29 ')' + 0x00,0x10,0x08,0x04,0x04,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x10,0x00,0x00,0x00, + + 8, // 0x2a '*' + 0x00,0x00,0x00,0x00,0x66,0x24,0x18,0xff,0x18,0x24,0x66,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2b '+' + 0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x7f,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x20,0x00, + + 8, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + + 8, // 0x2f '/' + 0x00,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00,0x00, + + 8, // 0x30 '0' + 0x00,0x00,0x3c,0x42,0x42,0x46,0x4a,0x52,0x62,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x31 '1' + 0x00,0x00,0x08,0x08,0x18,0x38,0x08,0x08,0x08,0x08,0x08,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x32 '2' + 0x00,0x00,0x3c,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x33 '3' + 0x00,0x00,0x7e,0x42,0x04,0x08,0x1c,0x02,0x02,0x02,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x34 '4' + 0x00,0x00,0x04,0x08,0x10,0x24,0x44,0x44,0x7e,0x04,0x04,0x0e,0x00,0x00,0x00,0x00, + + 8, // 0x35 '5' + 0x00,0x00,0x7e,0x42,0x40,0x40,0x7c,0x02,0x02,0x02,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x36 '6' + 0x00,0x00,0x1c,0x20,0x40,0x40,0x7c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x37 '7' + 0x00,0x00,0x7e,0x42,0x42,0x02,0x04,0x08,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, + + 8, // 0x38 '8' + 0x00,0x00,0x3c,0x42,0x42,0x42,0x3c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x39 '9' + 0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3e,0x02,0x02,0x04,0x38,0x00,0x00,0x00,0x00, + + 8, // 0x3a ':' + 0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3b ';' + 0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x40,0x00, + + 8, // 0x3c '<' + 0x00,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x02,0x00,0x00,0x00,0x00, + + 8, // 0x3d '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3e '>' + 0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x00,0x00,0x00,0x00, + + 8, // 0x3f '?' + 0x00,0x00,0x3c,0x42,0x42,0x42,0x04,0x08,0x08,0x00,0x08,0x08,0x00,0x00,0x00,0x00, + + 8, // 0x40 '@' + 0x00,0x00,0x3c,0x42,0x01,0x39,0x49,0x49,0x49,0x49,0x49,0x36,0x00,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x7e,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x7c,0x22,0x22,0x22,0x3c,0x22,0x22,0x22,0x22,0x7c,0x00,0x00,0x00,0x00, + + 8, // 0x43 'C' + 0x00,0x00,0x3c,0x42,0x42,0x40,0x40,0x40,0x40,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x44 'D' + 0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x7c,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x7e,0x22,0x20,0x28,0x38,0x28,0x20,0x20,0x22,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x7e,0x22,0x20,0x28,0x38,0x28,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + + 8, // 0x47 'G' + 0x00,0x00,0x3c,0x42,0x42,0x40,0x40,0x4e,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x48 'H' + 0x00,0x00,0x42,0x42,0x42,0x42,0x7e,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, + + 8, // 0x49 'I' + 0x00,0x00,0x1c,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x4a 'J' + 0x00,0x00,0x0e,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x44,0x38,0x00,0x00,0x00,0x00, + + 8, // 0x4b 'K' + 0x00,0x00,0x62,0x22,0x24,0x28,0x30,0x28,0x24,0x22,0x22,0x62,0x00,0x00,0x00,0x00, + + 8, // 0x4c 'L' + 0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x4d 'M' + 0x00,0x00,0x41,0x63,0x55,0x49,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00, + + 8, // 0x4e 'N' + 0x00,0x00,0x42,0x42,0x62,0x52,0x4a,0x46,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, + + 8, // 0x4f 'O' + 0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x3c,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + + 8, // 0x51 'Q' + 0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x42,0x4a,0x44,0x3a,0x02,0x00,0x00,0x00, + + 8, // 0x52 'R' + 0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x3c,0x28,0x24,0x22,0x62,0x00,0x00,0x00,0x00, + + 8, // 0x53 'S' + 0x00,0x00,0x3c,0x42,0x42,0x40,0x30,0x0c,0x02,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x54 'T' + 0x00,0x00,0x7f,0x49,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x55 'U' + 0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x41,0x41,0x41,0x41,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00,0x00,0x00, + + 8, // 0x57 'W' + 0x00,0x00,0x41,0x41,0x41,0x41,0x41,0x49,0x49,0x55,0x63,0x41,0x00,0x00,0x00,0x00, + + 8, // 0x58 'X' + 0x00,0x00,0x42,0x42,0x42,0x24,0x18,0x18,0x24,0x42,0x42,0x42,0x00,0x00,0x00,0x00, + + 8, // 0x59 'Y' + 0x00,0x00,0x22,0x22,0x22,0x22,0x14,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x5a 'Z' + 0x00,0x00,0x7e,0x42,0x02,0x04,0x08,0x10,0x20,0x40,0x42,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x5b '[' + 0x00,0x1e,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1e,0x00,0x00,0x00, + + 8, // 0x5c '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x00,0x00,0x00, + + 8, // 0x5d ']' + 0x00,0x3c,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x3c,0x00,0x00,0x00, + + 8, // 0x5e '^' + 0x00,0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00, + + 8, // 0x60 '`' + 0x00,0x00,0x08,0x08,0x08,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x3c,0x44,0x44,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x60,0x20,0x20,0x38,0x24,0x22,0x22,0x22,0x22,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x40,0x40,0x40,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x0c,0x04,0x04,0x1c,0x24,0x44,0x44,0x44,0x44,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x7e,0x40,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x66 'f' + 0x00,0x00,0x0c,0x12,0x10,0x10,0x38,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x44,0x38,0x00, + + 8, // 0x68 'h' + 0x00,0x00,0x60,0x20,0x20,0x2c,0x32,0x22,0x22,0x22,0x22,0x62,0x00,0x00,0x00,0x00, + + 8, // 0x69 'i' + 0x00,0x00,0x08,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x6a 'j' + 0x00,0x00,0x04,0x04,0x00,0x0c,0x04,0x04,0x04,0x04,0x04,0x44,0x44,0x38,0x00,0x00, + + 8, // 0x6b 'k' + 0x00,0x00,0x60,0x20,0x20,0x22,0x24,0x28,0x38,0x24,0x22,0x62,0x00,0x00,0x00,0x00, + + 8, // 0x6c 'l' + 0x00,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x6d 'm' + 0x00,0x00,0x00,0x00,0x00,0x76,0x49,0x49,0x49,0x49,0x41,0x41,0x00,0x00,0x00,0x00, + + 8, // 0x6e 'n' + 0x00,0x00,0x00,0x00,0x00,0x5c,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00, + + 8, // 0x6f 'o' + 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x22,0x3c,0x20,0x20,0x70,0x00, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x04,0x0e,0x00, + + 8, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x7c,0x22,0x22,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x40,0x3c,0x02,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x74 't' + 0x00,0x00,0x10,0x10,0x10,0x7c,0x10,0x10,0x10,0x10,0x12,0x0c,0x00,0x00,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x41,0x41,0x41,0x41,0x22,0x14,0x08,0x00,0x00,0x00,0x00, + + 8, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x41,0x41,0x41,0x49,0x49,0x55,0x22,0x00,0x00,0x00,0x00, + + 8, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x00,0x00,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x3e,0x02,0x04,0x78,0x00, + + 8, // 0x7a 'z' + 0x00,0x00,0x00,0x00,0x00,0x7e,0x44,0x08,0x10,0x20,0x42,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x7b '{' + 0x00,0x06,0x08,0x08,0x08,0x08,0x08,0x30,0x08,0x08,0x08,0x08,0x08,0x06,0x00,0x00, + + 8, // 0x7c '|' + 0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00, + + 8, // 0x7d '}' + 0x00,0x30,0x08,0x08,0x08,0x08,0x08,0x06,0x08,0x08,0x08,0x08,0x08,0x30,0x00,0x00, + + 8, // 0x7e '~' + 0x00,0x00,0x39,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x7f '' + 0x00,0x00,0x00,0x00,0x00,0x08,0x14,0x22,0x41,0x41,0x7f,0x00,0x00,0x00,0x00,0x00, + 0 + }; + + const int8u gse8x16_bold[] = + { + 16, 0, 32, 128-32, + + 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x44,0x00,0x55,0x00,0x66,0x00,0x77,0x00,0x88,0x00, + 0x99,0x00,0xaa,0x00,0xbb,0x00,0xcc,0x00,0xdd,0x00,0xee,0x00,0xff,0x00,0x10,0x01,0x21,0x01, + 0x32,0x01,0x43,0x01,0x54,0x01,0x65,0x01,0x76,0x01,0x87,0x01,0x98,0x01,0xa9,0x01,0xba,0x01, + 0xcb,0x01,0xdc,0x01,0xed,0x01,0xfe,0x01,0x0f,0x02,0x20,0x02,0x31,0x02,0x42,0x02,0x53,0x02, + 0x64,0x02,0x75,0x02,0x86,0x02,0x97,0x02,0xa8,0x02,0xb9,0x02,0xca,0x02,0xdb,0x02,0xec,0x02, + 0xfd,0x02,0x0e,0x03,0x1f,0x03,0x30,0x03,0x41,0x03,0x52,0x03,0x63,0x03,0x74,0x03,0x85,0x03, + 0x96,0x03,0xa7,0x03,0xb8,0x03,0xc9,0x03,0xda,0x03,0xeb,0x03,0xfc,0x03,0x0d,0x04,0x1e,0x04, + 0x2f,0x04,0x40,0x04,0x51,0x04,0x62,0x04,0x73,0x04,0x84,0x04,0x95,0x04,0xa6,0x04,0xb7,0x04, + 0xc8,0x04,0xd9,0x04,0xea,0x04,0xfb,0x04,0x0c,0x05,0x1d,0x05,0x2e,0x05,0x3f,0x05,0x50,0x05, + 0x61,0x05,0x72,0x05,0x83,0x05,0x94,0x05,0xa5,0x05,0xb6,0x05,0xc7,0x05,0xd8,0x05,0xe9,0x05, + 0xfa,0x05,0x0b,0x06,0x1c,0x06,0x2d,0x06,0x3e,0x06,0x4f,0x06, + + 8, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x21 '!' + 0x00,0x00,0x18,0x3c,0x3c,0x3c,0x3c,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + + 8, // 0x22 '"' + 0x00,0x66,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x23 '#' + 0x00,0x00,0x66,0x66,0x66,0xff,0x66,0x66,0xff,0x66,0x66,0x66,0x00,0x00,0x00,0x00, + + 8, // 0x24 '$' + 0x00,0x08,0x08,0x3e,0x6b,0x6b,0x68,0x3e,0x0b,0x6b,0x6b,0x3e,0x08,0x08,0x00,0x00, + + 8, // 0x25 '%' + 0x00,0x00,0x66,0xbe,0xcc,0x0c,0x18,0x18,0x30,0x33,0x65,0x66,0x00,0x00,0x00,0x00, + + 8, // 0x26 '&' + 0x00,0x00,0x1c,0x36,0x36,0x36,0x1c,0x3b,0x6e,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, + + 8, // 0x27 ''' + 0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x28 '(' + 0x00,0x06,0x0c,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0c,0x06,0x00,0x00,0x00, + + 8, // 0x29 ')' + 0x00,0x30,0x18,0x0c,0x0c,0x06,0x06,0x06,0x06,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00, + + 8, // 0x2a '*' + 0x00,0x00,0x00,0x00,0x66,0x24,0x18,0xff,0x18,0x24,0x66,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2b '+' + 0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x20,0x00, + + 8, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + + 8, // 0x2f '/' + 0x00,0x03,0x03,0x06,0x06,0x0c,0x0c,0x18,0x18,0x30,0x30,0x60,0x60,0x00,0x00,0x00, + + 8, // 0x30 '0' + 0x00,0x00,0x3e,0x63,0x63,0x67,0x6b,0x73,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x31 '1' + 0x00,0x00,0x0c,0x0c,0x1c,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3f,0x00,0x00,0x00,0x00, + + 8, // 0x32 '2' + 0x00,0x00,0x3e,0x63,0x63,0x03,0x06,0x0c,0x18,0x30,0x61,0x7f,0x00,0x00,0x00,0x00, + + 8, // 0x33 '3' + 0x00,0x00,0x7f,0x43,0x06,0x0c,0x1e,0x03,0x03,0x03,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x34 '4' + 0x00,0x00,0x06,0x0c,0x18,0x32,0x66,0x66,0x7f,0x06,0x06,0x0f,0x00,0x00,0x00,0x00, + + 8, // 0x35 '5' + 0x00,0x00,0x7f,0x61,0x60,0x60,0x7e,0x03,0x03,0x03,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x36 '6' + 0x00,0x00,0x1e,0x30,0x60,0x60,0x7e,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x37 '7' + 0x00,0x00,0x7f,0x63,0x63,0x03,0x06,0x0c,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, + + 8, // 0x38 '8' + 0x00,0x00,0x3e,0x63,0x63,0x63,0x3e,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x39 '9' + 0x00,0x00,0x3e,0x63,0x63,0x63,0x63,0x3f,0x03,0x03,0x06,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x3a ':' + 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3b ';' + 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x40,0x00, + + 8, // 0x3c '<' + 0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00, + + 8, // 0x3d '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3e '>' + 0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x03,0x06,0x0c,0x18,0x30,0x00,0x00,0x00,0x00, + + 8, // 0x3f '?' + 0x00,0x00,0x3e,0x63,0x63,0x63,0x06,0x0c,0x0c,0x00,0x0c,0x0c,0x00,0x00,0x00,0x00, + + 8, // 0x40 '@' + 0x00,0x00,0x7c,0x86,0x03,0x73,0xdb,0xdb,0xdb,0xdb,0xdb,0x6e,0x00,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x08,0x1c,0x36,0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x7e,0x33,0x33,0x33,0x3e,0x33,0x33,0x33,0x33,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x43 'C' + 0x00,0x00,0x1e,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x44 'D' + 0x00,0x00,0x7c,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7c,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x7f,0x33,0x31,0x34,0x3c,0x34,0x30,0x31,0x33,0x7f,0x00,0x00,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x7f,0x33,0x31,0x34,0x3c,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, + + 8, // 0x47 'G' + 0x00,0x00,0x1f,0x33,0x61,0x60,0x60,0x6f,0x63,0x63,0x33,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x48 'H' + 0x00,0x00,0x63,0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x49 'I' + 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x4a 'J' + 0x00,0x00,0x0f,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x4b 'K' + 0x00,0x00,0x73,0x33,0x36,0x36,0x3c,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00, + + 8, // 0x4c 'L' + 0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7f,0x00,0x00,0x00,0x00, + + 8, // 0x4d 'M' + 0x00,0x00,0x63,0x63,0x77,0x77,0x7f,0x6b,0x6b,0x63,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x4e 'N' + 0x00,0x00,0x63,0x63,0x73,0x7b,0x6f,0x67,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x4f 'O' + 0x00,0x00,0x1c,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x7e,0x33,0x33,0x33,0x33,0x3e,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, + + 8, // 0x51 'Q' + 0x00,0x00,0x1c,0x36,0x63,0x63,0x63,0x63,0x63,0x6f,0x36,0x1e,0x03,0x00,0x00,0x00, + + 8, // 0x52 'R' + 0x00,0x00,0x7e,0x33,0x33,0x33,0x33,0x3e,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00, + + 8, // 0x53 'S' + 0x00,0x00,0x3e,0x63,0x63,0x30,0x18,0x0c,0x06,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x54 'T' + 0x00,0x00,0x3f,0x3f,0x2d,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x55 'U' + 0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1c,0x08,0x00,0x00,0x00,0x00, + + 8, // 0x57 'W' + 0x00,0x00,0x63,0x63,0x63,0x6b,0x6b,0x7f,0x77,0x77,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x58 'X' + 0x00,0x00,0x63,0x63,0x63,0x36,0x1c,0x1c,0x36,0x63,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x59 'Y' + 0x00,0x00,0x33,0x33,0x33,0x33,0x1e,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x5a 'Z' + 0x00,0x00,0x7f,0x63,0x43,0x06,0x0c,0x18,0x30,0x61,0x63,0x7f,0x00,0x00,0x00,0x00, + + 8, // 0x5b '[' + 0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00, + + 8, // 0x5c '\' + 0x00,0x60,0x60,0x30,0x30,0x18,0x18,0x0c,0x0c,0x06,0x06,0x03,0x03,0x00,0x00,0x00, + + 8, // 0x5d ']' + 0x00,0x7c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x7c,0x00,0x00,0x00, + + 8, // 0x5e '^' + 0x00,0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00, + + 8, // 0x60 '`' + 0x00,0x00,0x18,0x18,0x18,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x06,0x3e,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x70,0x30,0x30,0x3c,0x36,0x33,0x33,0x33,0x33,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x60,0x60,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x0e,0x06,0x06,0x1e,0x36,0x66,0x66,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x7f,0x60,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x66 'f' + 0x00,0x00,0x0e,0x1b,0x1b,0x18,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3b,0x66,0x66,0x66,0x66,0x66,0x3e,0x06,0x66,0x3c,0x00, + + 8, // 0x68 'h' + 0x00,0x00,0x70,0x30,0x30,0x36,0x3b,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00, + + 8, // 0x69 'i' + 0x00,0x00,0x0c,0x0c,0x00,0x1c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x6a 'j' + 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,0x00, + + 8, // 0x6b 'k' + 0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3c,0x36,0x33,0x73,0x00,0x00,0x00,0x00, + + 8, // 0x6c 'l' + 0x00,0x00,0x1c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x6d 'm' + 0x00,0x00,0x00,0x00,0x00,0x76,0x7f,0x6b,0x6b,0x6b,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x6e 'n' + 0x00,0x00,0x00,0x00,0x00,0x6e,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00, + + 8, // 0x6f 'o' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x6e,0x33,0x33,0x33,0x33,0x33,0x3e,0x30,0x30,0x78,0x00, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3b,0x66,0x66,0x66,0x66,0x66,0x3e,0x06,0x06,0x0f,0x00, + + 8, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x60,0x3e,0x03,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x74 't' + 0x00,0x00,0x08,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x1b,0x0e,0x00,0x00,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x36,0x1c,0x08,0x00,0x00,0x00,0x00, + + 8, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x6b,0x6b,0x7f,0x36,0x36,0x00,0x00,0x00,0x00, + + 8, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x1c,0x36,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x3f,0x03,0x06,0x7c,0x00, + + 8, // 0x7a 'z' + 0x00,0x00,0x00,0x00,0x00,0x7f,0x63,0x06,0x0c,0x18,0x31,0x7f,0x00,0x00,0x00,0x00, + + 8, // 0x7b '{' + 0x00,0x03,0x04,0x0c,0x0c,0x0c,0x08,0x30,0x08,0x0c,0x0c,0x0c,0x04,0x03,0x00,0x00, + + 8, // 0x7c '|' + 0x00,0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x00,0x00,0x00, + + 8, // 0x7d '}' + 0x00,0x60,0x10,0x18,0x18,0x18,0x08,0x06,0x08,0x18,0x18,0x18,0x10,0x60,0x00,0x00, + + 8, // 0x7e '~' + 0x00,0x00,0x3b,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x7f '' + 0x00,0x00,0x00,0x00,0x00,0x08,0x1c,0x36,0x63,0x63,0x7f,0x00,0x00,0x00,0x00,0x00, + 0 + }; + + const int8u mcs11_prop[] = + { + 11, 2, 32, 128-32, + 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, + 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, + 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, + 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, + 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, + 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, + 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, + + 4, // 0x22 '"' + 0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x00, + + 6, // 0x24 '$' + 0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10, + + 6, // 0x25 '%' + 0x00,0x00,0x68,0xA8,0xD0,0x10,0x20,0x2C,0x54,0x58,0x00, + + 6, // 0x26 '&' + 0x00,0x20,0x50,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00, + + 3, // 0x27 ''' + 0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x28 '(' + 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 5, // 0x29 ')' + 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + + 6, // 0x2A '*' + 0x00,0x00,0x28,0x7C,0x38,0x7C,0x28,0x00,0x00,0x00,0x00, + + 6, // 0x2B '+' + 0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00, + + 7, // 0x2F '/' + 0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40, + + 6, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00, + + 4, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 6, // 0x32 '2' + 0x00,0x38,0x44,0x44,0x04,0x08,0x10,0x20,0x40,0x7C,0x00, + + 6, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00, + + 6, // 0x34 '4' + 0x00,0x08,0x18,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00, + + 6, // 0x35 '5' + 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00, + + 6, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x40,0x78,0x44,0x44,0x44,0x38,0x00, + + 6, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00, + + 6, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00, + + 6, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0xC0, + + 6, // 0x3C '<' + 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, + + 6, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, + + 6, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00, + + 6, // 0x40 '@' + 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00, + + 6, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00, + + 6, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00, + + 6, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00, + + 6, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00, + + 6, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00, + + 6, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00, + + 6, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00, + + 6, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00, + + 4, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 6, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x08,0x48,0x30,0x00, + + 6, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00, + + 6, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00, + + 8, // 0x4D 'M' + 0x00,0x41,0x63,0x55,0x49,0x49,0x41,0x41,0x41,0x41,0x00, + + 7, // 0x4E 'N' + 0x00,0x42,0x42,0x62,0x52,0x4A,0x46,0x42,0x42,0x42,0x00, + + 6, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00, + + 6, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x40,0x00, + + 6, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00, + + 6, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x44,0x00, + + 6, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00, + + 6, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, + + 6, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00, + + 6, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00, + + 8, // 0x57 'W' + 0x00,0x41,0x41,0x41,0x41,0x49,0x49,0x49,0x55,0x22,0x00, + + 6, // 0x58 'X' + 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00, + + 6, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x10,0x00, + + 6, // 0x5A 'Z' + 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00, + + 5, // 0x5B '[' + 0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30, + + 7, // 0x5C '\' + 0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, + + 4, // 0x5D ']' + 0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, + + 6, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00, + + 4, // 0x60 '`' + 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00, + + 6, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00, + + 6, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00, + + 4, // 0x66 'f' + 0x00,0x10,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x44,0x38, + + 6, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00, + + 2, // 0x69 'i' + 0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, + + 3, // 0x6A 'j' + 0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + + 5, // 0x6B 'k' + 0x00,0x40,0x40,0x48,0x50,0x60,0x60,0x50,0x48,0x48,0x00, + + 2, // 0x6C 'l' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, + + 8, // 0x6D 'm' + 0x00,0x00,0x00,0x76,0x49,0x49,0x49,0x49,0x41,0x41,0x00, + + 6, // 0x6E 'n' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00, + + 6, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x20,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00, + + 5, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x28,0x10,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00, + + 8, // 0x77 'w' + 0x00,0x00,0x00,0x41,0x41,0x41,0x41,0x49,0x49,0x36,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x3C,0x04,0x08,0x70, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00, + + 5, // 0x7B '{' + 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18, + + 3, // 0x7C '|' + 0x00,0x40,0x40,0x40,0x40,0x00,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0, + + 6, // 0x7E '~' + 0x00,0x24,0x54,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs11_prop_condensed[] = + { + 11, 2, 32, 128-32, + 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, + 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, + 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, + 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, + 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, + 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, + 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, + + 3, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x21 '!' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x40,0x00, + + 4, // 0x22 '"' + 0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x23 '#' + 0x00,0x50,0x50,0xF8,0x50,0x50,0x50,0xF8,0x50,0x50,0x00, + + 5, // 0x24 '$' + 0x00,0x40,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x20,0x00, + + 5, // 0x25 '%' + 0x00,0x00,0x90,0x90,0x20,0x20,0x40,0x40,0x90,0x90,0x00, + + 5, // 0x26 '&' + 0x00,0x40,0xA0,0xA0,0xA0,0x40,0xA8,0x90,0x90,0x68,0x00, + + 5, // 0x27 ''' + 0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 4, // 0x29 ')' + 0x80,0x40,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80, + + 5, // 0x2A '*' + 0x00,0x00,0x90,0x60,0xF0,0x60,0x90,0x00,0x00,0x00,0x00, + + 5, // 0x2B '+' + 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00, + + 6, // 0x2F '/' + 0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, + + 5, // 0x30 '0' + 0x00,0x70,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, + + 3, // 0x31 '1' + 0x00,0x40,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x32 '2' + 0x00,0x60,0x90,0x90,0x10,0x10,0x20,0x40,0x80,0xF0,0x00, + + 5, // 0x33 '3' + 0x00,0x60,0x90,0x10,0x10,0x60,0x10,0x10,0x90,0x60,0x00, + + 5, // 0x34 '4' + 0x00,0x10,0x30,0x30,0x50,0x50,0x90,0xF0,0x10,0x10,0x00, + + 5, // 0x35 '5' + 0x00,0xF0,0x80,0x80,0xE0,0x90,0x10,0x10,0x90,0x60,0x00, + + 5, // 0x36 '6' + 0x00,0x60,0x90,0x80,0x80,0xE0,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x37 '7' + 0x00,0xF0,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00, + + 5, // 0x38 '8' + 0x00,0x60,0x90,0x90,0x90,0x60,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x39 '9' + 0x00,0x60,0x90,0x90,0x90,0x70,0x10,0x10,0x90,0x60,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0xC0, + + 6, // 0x3C '<' + 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00, + + 5, // 0x3D '=' + 0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00, + + 5, // 0x3F '?' + 0x00,0x60,0x90,0x10,0x10,0x20,0x40,0x00,0x40,0x00,0x00, + + 5, // 0x40 '@' + 0x00,0x60,0x90,0x90,0xB0,0xB0,0xB0,0x80,0x80,0x70,0x00, + + 5, // 0x41 'A' + 0x00,0x60,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x42 'B' + 0x00,0xE0,0x90,0x90,0x90,0xE0,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x43 'C' + 0x00,0x60,0x90,0x80,0x80,0x80,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x44 'D' + 0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x45 'E' + 0x00,0xF0,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0xF0,0x00, + + 5, // 0x46 'F' + 0x00,0xF0,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0x80,0x00, + + 5, // 0x47 'G' + 0x00,0x70,0x80,0x80,0x80,0xB0,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x48 'H' + 0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x90,0x00, + + 4, // 0x49 'I' + 0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xE0,0x00, + + 5, // 0x4A 'J' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0xA0,0xA0,0x40,0x00, + + 5, // 0x4B 'K' + 0x00,0x90,0x90,0xA0,0xA0,0xC0,0xA0,0xA0,0x90,0x90,0x00, + + 5, // 0x4C 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF0,0x00, + + 6, // 0x4D 'M' + 0x00,0x88,0xD8,0xA8,0xA8,0xA8,0x88,0x88,0x88,0x88,0x00, + + 5, // 0x4E 'N' + 0x00,0x90,0x90,0xD0,0xD0,0xB0,0xB0,0x90,0x90,0x90,0x00, + + 5, // 0x4F 'O' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x50 'P' + 0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0x80,0x80,0x80,0x00, + + 5, // 0x51 'Q' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x30, + + 5, // 0x52 'R' + 0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0xA0,0x90,0x90,0x00, + + 5, // 0x53 'S' + 0x00,0x60,0x90,0x80,0x80,0x60,0x10,0x10,0x90,0x60,0x00, + + 6, // 0x54 'T' + 0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x55 'U' + 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 6, // 0x56 'V' + 0x00,0x88,0x88,0x88,0x88,0x50,0x50,0x50,0x20,0x20,0x00, + + 6, // 0x57 'W' + 0x00,0x88,0x88,0x88,0xA8,0xA8,0xA8,0xA8,0xA8,0x50,0x00, + + 5, // 0x58 'X' + 0x00,0x90,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x90,0x00, + + 6, // 0x59 'Y' + 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x5A 'Z' + 0x00,0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0xF0,0x00, + + 4, // 0x5B '[' + 0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60,0x00, + + 6, // 0x5C '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, + + 4, // 0x5D ']' + 0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0x00, + + 5, // 0x5E '^' + 0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00, + + 5, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x61 'a' + 0x00,0x00,0x00,0x60,0x90,0x10,0x70,0x90,0x90,0x70,0x00, + + 5, // 0x62 'b' + 0x00,0x80,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x00,0x60,0x90,0x80,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x64 'd' + 0x00,0x10,0x10,0x10,0x70,0x90,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x65 'e' + 0x00,0x00,0x00,0x60,0x90,0x90,0xF0,0x80,0x90,0x60,0x00, + + 4, // 0x66 'f' + 0x00,0x20,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x67 'g' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0x90,0x60, + + 5, // 0x68 'h' + 0x00,0x80,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0x90,0x00, + + 2, // 0x69 'i' + 0x00,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, + + 4, // 0x6A 'j' + 0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + + 5, // 0x6B 'k' + 0x00,0x80,0x80,0x90,0x90,0xA0,0xC0,0xA0,0x90,0x90,0x00, + + 2, // 0x6C 'l' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, + + 6, // 0x6D 'm' + 0x00,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0x88,0x88,0x88,0x00, + + 5, // 0x6E 'n' + 0x00,0x00,0x00,0xA0,0xD0,0x90,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x6F 'o' + 0x00,0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x70 'p' + 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0x80,0x80, + + 5, // 0x71 'q' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x90,0x70,0x10,0x10, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0xB8,0x48,0x40,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x00,0x60,0x90,0x40,0x20,0x10,0x90,0x60,0x00, + + 4, // 0x74 't' + 0x00,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x20,0x00, + + 5, // 0x75 'u' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x70,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00, + + 6, // 0x77 'w' + 0x00,0x00,0x00,0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00, + + 5, // 0x78 'x' + 0x00,0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00, + + 5, // 0x79 'y' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x70,0x10,0x20,0xC0, + + 5, // 0x7A 'z' + 0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0x80,0xF0,0x00, + + 5, // 0x7B '{' + 0x30,0x40,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x30, + + 3, // 0x7C '|' + 0x00,0x40,0x40,0x40,0x40,0x00,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0xC0, + + 5, // 0x7E '~' + 0x00,0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x7F '' + 0x00,0x20,0x70,0xD8,0x88,0x88,0xF8,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs12_prop[] = + { + 12, 3, 32, 128-32, + 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4E,0x00,0x5B,0x00,0x68,0x00, + 0x75,0x00,0x82,0x00,0x8F,0x00,0x9C,0x00,0xA9,0x00,0xB6,0x00,0xC3,0x00,0xD0,0x00,0xDD,0x00, + 0xEA,0x00,0xF7,0x00,0x04,0x01,0x11,0x01,0x1E,0x01,0x2B,0x01,0x38,0x01,0x45,0x01,0x52,0x01, + 0x5F,0x01,0x6C,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xA0,0x01,0xAD,0x01,0xBA,0x01,0xC7,0x01, + 0xD4,0x01,0xE1,0x01,0xEE,0x01,0xFB,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2F,0x02,0x3C,0x02, + 0x49,0x02,0x62,0x02,0x6F,0x02,0x7C,0x02,0x89,0x02,0x96,0x02,0xA3,0x02,0xB0,0x02,0xBD,0x02, + 0xCA,0x02,0xD7,0x02,0xF0,0x02,0xFD,0x02,0x0A,0x03,0x17,0x03,0x24,0x03,0x31,0x03,0x3E,0x03, + 0x4B,0x03,0x58,0x03,0x65,0x03,0x72,0x03,0x7F,0x03,0x8C,0x03,0x99,0x03,0xA6,0x03,0xB3,0x03, + 0xC0,0x03,0xCD,0x03,0xDA,0x03,0xE7,0x03,0xF4,0x03,0x01,0x04,0x1A,0x04,0x27,0x04,0x34,0x04, + 0x41,0x04,0x4E,0x04,0x5B,0x04,0x68,0x04,0x75,0x04,0x82,0x04,0x8F,0x04,0xA8,0x04,0xB5,0x04, + 0xC2,0x04,0xCF,0x04,0xDC,0x04,0xE9,0x04,0xF6,0x04,0x03,0x05, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 4, // 0x22 '"' + 0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x00, + + 6, // 0x24 '$' + 0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10,0x00, + + 7, // 0x25 '%' + 0x32,0x54,0x64,0x08,0x08,0x10,0x10,0x26,0x2A,0x4C,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x30,0x48,0x48,0x48,0x30,0x4A,0x4A,0x44,0x3A,0x00,0x00, + + 3, // 0x27 ''' + 0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x00, + + 5, // 0x29 ')' + 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x00, + + 6, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00, + + 6, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x40,0x80, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 7, // 0x2F '/' + 0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00, + + 7, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00,0x00, + + 4, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x28,0x48,0x48,0x7C,0x08,0x08,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x40,0x80, + + 6, // 0x3C '<' + 0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, + + 6, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, + + 6, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, + + 6, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 9, // 0x4D 'M' + 0x00,0x00,0x41,0x00,0x63,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x4E 'N' + 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,0x00, + + 7, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, + + 9, // 0x57 'W' + 0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x22,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x5A 'Z' + 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00, + + 4, // 0x5B '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, + + 7, // 0x5C '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, + + 4, // 0x5D ']' + 0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00, + + 6, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, + + 4, // 0x60 '`' + 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, + + 4, // 0x66 'f' + 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x78, + + 7, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60, + + 6, // 0x6B 'k' + 0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 9, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x6E 'n' + 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x18,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, + + 9, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x36,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x08,0x70, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 5, // 0x7B '{' + 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, + + 3, // 0x7C '|' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0,0x00, + + 7, // 0x7E '~' + 0x00,0x60,0x92,0x92,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs13_prop[] = + { + 13, 4, 32, 128-32, + 0x00,0x00,0x0E,0x00,0x1C,0x00,0x2A,0x00,0x38,0x00,0x46,0x00,0x54,0x00,0x62,0x00,0x70,0x00, + 0x7E,0x00,0x8C,0x00,0x9A,0x00,0xA8,0x00,0xB6,0x00,0xC4,0x00,0xD2,0x00,0xE0,0x00,0xEE,0x00, + 0xFC,0x00,0x0A,0x01,0x18,0x01,0x26,0x01,0x34,0x01,0x42,0x01,0x50,0x01,0x5E,0x01,0x6C,0x01, + 0x7A,0x01,0x88,0x01,0x96,0x01,0xA4,0x01,0xB2,0x01,0xC0,0x01,0xCE,0x01,0xDC,0x01,0xEA,0x01, + 0xF8,0x01,0x06,0x02,0x14,0x02,0x22,0x02,0x30,0x02,0x3E,0x02,0x4C,0x02,0x5A,0x02,0x68,0x02, + 0x76,0x02,0x91,0x02,0x9F,0x02,0xAD,0x02,0xBB,0x02,0xC9,0x02,0xD7,0x02,0xE5,0x02,0xF3,0x02, + 0x01,0x03,0x0F,0x03,0x2A,0x03,0x38,0x03,0x46,0x03,0x54,0x03,0x62,0x03,0x70,0x03,0x7E,0x03, + 0x8C,0x03,0x9A,0x03,0xA8,0x03,0xB6,0x03,0xC4,0x03,0xD2,0x03,0xE0,0x03,0xEE,0x03,0xFC,0x03, + 0x0A,0x04,0x18,0x04,0x26,0x04,0x34,0x04,0x42,0x04,0x50,0x04,0x6B,0x04,0x79,0x04,0x87,0x04, + 0x95,0x04,0xA3,0x04,0xB1,0x04,0xBF,0x04,0xCD,0x04,0xDB,0x04,0xE9,0x04,0x04,0x05,0x12,0x05, + 0x20,0x05,0x2E,0x05,0x3C,0x05,0x4A,0x05,0x58,0x05,0x66,0x05, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 4, // 0x22 '"' + 0x00,0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x00, + + 6, // 0x24 '$' + 0x00,0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10,0x00, + + 7, // 0x25 '%' + 0x00,0x32,0x54,0x64,0x08,0x08,0x10,0x10,0x26,0x2A,0x4C,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x30,0x48,0x48,0x48,0x30,0x4A,0x4A,0x44,0x3A,0x00,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x00,0x00, + + 5, // 0x29 ')' + 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x00,0x00, + + 6, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00,0x00, + + 6, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x20,0x40,0x80, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, + + 7, // 0x2F '/' + 0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00,0x00,0x00, + + 4, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x28,0x48,0x48,0x7C,0x08,0x08,0x00,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x20,0x40,0x80, + + 6, // 0x3C '<' + 0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, + + 6, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, + + 6, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00,0x00, + + 6, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, + + 9, // 0x4D 'M' + 0x00,0x00,0x41,0x00,0x63,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x4E 'N' + 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 6, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 9, // 0x57 'W' + 0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 6, // 0x5A 'Z' + 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00,0x00, + + 4, // 0x5B '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00,0x00, + + 7, // 0x5C '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00,0x00, + + 4, // 0x5D ']' + 0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00,0x00, + + 6, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00, + + 4, // 0x60 '`' + 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,0x00,0x00, + + 4, // 0x66 'f' + 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x44,0x38, + + 7, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00, + + 6, // 0x6B 'k' + 0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 9, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x6E 'n' + 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04,0x04, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x18,0x00,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 9, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x08,0x70, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, + + 5, // 0x7B '{' + 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00,0x00, + + 3, // 0x7C '|' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0,0x00,0x00, + + 7, // 0x7E '~' + 0x00,0x60,0x92,0x92,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs5x10_mono[] = + { + 10, 2, 32, 128-32, + 0x00,0x00,0x0B,0x00,0x16,0x00,0x21,0x00,0x2C,0x00,0x37,0x00,0x42,0x00,0x4D,0x00,0x58,0x00, + 0x63,0x00,0x6E,0x00,0x79,0x00,0x84,0x00,0x8F,0x00,0x9A,0x00,0xA5,0x00,0xB0,0x00,0xBB,0x00, + 0xC6,0x00,0xD1,0x00,0xDC,0x00,0xE7,0x00,0xF2,0x00,0xFD,0x00,0x08,0x01,0x13,0x01,0x1E,0x01, + 0x29,0x01,0x34,0x01,0x3F,0x01,0x4A,0x01,0x55,0x01,0x60,0x01,0x6B,0x01,0x76,0x01,0x81,0x01, + 0x8C,0x01,0x97,0x01,0xA2,0x01,0xAD,0x01,0xB8,0x01,0xC3,0x01,0xCE,0x01,0xD9,0x01,0xE4,0x01, + 0xEF,0x01,0xFA,0x01,0x05,0x02,0x10,0x02,0x1B,0x02,0x26,0x02,0x31,0x02,0x3C,0x02,0x47,0x02, + 0x52,0x02,0x5D,0x02,0x68,0x02,0x73,0x02,0x7E,0x02,0x89,0x02,0x94,0x02,0x9F,0x02,0xAA,0x02, + 0xB5,0x02,0xC0,0x02,0xCB,0x02,0xD6,0x02,0xE1,0x02,0xEC,0x02,0xF7,0x02,0x02,0x03,0x0D,0x03, + 0x18,0x03,0x23,0x03,0x2E,0x03,0x39,0x03,0x44,0x03,0x4F,0x03,0x5A,0x03,0x65,0x03,0x70,0x03, + 0x7B,0x03,0x86,0x03,0x91,0x03,0x9C,0x03,0xA7,0x03,0xB2,0x03,0xBD,0x03,0xC8,0x03,0xD3,0x03, + 0xDE,0x03,0xE9,0x03,0xF4,0x03,0xFF,0x03,0x0A,0x04,0x15,0x04, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, + + 5, // 0x22 '"' + 0x00,0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x23 '#' + 0x00,0x50,0x50,0xF8,0x50,0x50,0x50,0xF8,0x50,0x50, + + 5, // 0x24 '$' + 0x00,0x40,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x20, + + 5, // 0x25 '%' + 0x00,0x00,0x90,0x90,0x20,0x20,0x40,0x40,0x90,0x90, + + 5, // 0x26 '&' + 0x00,0x40,0xA0,0xA0,0xA0,0x40,0xA8,0x90,0x90,0x68, + + 5, // 0x27 ''' + 0x00,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 5, // 0x29 ')' + 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + + 5, // 0x2A '*' + 0x00,0x00,0x90,0x60,0xF0,0x60,0x90,0x00,0x00,0x00, + + 5, // 0x2B '+' + 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00, + + 5, // 0x2F '/' + 0x00,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x00, + + 5, // 0x30 '0' + 0x00,0x70,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x32 '2' + 0x00,0x60,0x90,0x90,0x10,0x20,0x40,0x80,0xF0,0x00, + + 5, // 0x33 '3' + 0x00,0x60,0x90,0x10,0x60,0x10,0x10,0x90,0x60,0x00, + + 5, // 0x34 '4' + 0x00,0x10,0x30,0x50,0x50,0x90,0xF0,0x10,0x10,0x00, + + 5, // 0x35 '5' + 0x00,0xF0,0x80,0x80,0xE0,0x10,0x10,0x90,0x60,0x00, + + 5, // 0x36 '6' + 0x00,0x60,0x80,0x80,0xE0,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x37 '7' + 0x00,0xF0,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00, + + 5, // 0x38 '8' + 0x00,0x60,0x90,0x90,0x60,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x39 '9' + 0x00,0x60,0x90,0x90,0x90,0x70,0x10,0x10,0x60,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0xC0, + + 5, // 0x3C '<' + 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08, + + 5, // 0x3D '=' + 0x00,0x00,0x00,0x00,0xF0,0x00,0xF0,0x00,0x00,0x00, + + 5, // 0x3E '>' + 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80, + + 5, // 0x3F '?' + 0x00,0x60,0x90,0x10,0x10,0x20,0x40,0x00,0x40,0x00, + + 5, // 0x40 '@' + 0x00,0x60,0x90,0x90,0xB0,0xB0,0x80,0x80,0x70,0x00, + + 5, // 0x41 'A' + 0x00,0x60,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x00, + + 5, // 0x42 'B' + 0x00,0xE0,0x90,0x90,0xE0,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x43 'C' + 0x00,0x60,0x90,0x80,0x80,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x44 'D' + 0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x45 'E' + 0x00,0xF0,0x80,0x80,0xF0,0x80,0x80,0x80,0xF0,0x00, + + 5, // 0x46 'F' + 0x00,0xF0,0x80,0x80,0xF0,0x80,0x80,0x80,0x80,0x00, + + 5, // 0x47 'G' + 0x00,0x60,0x90,0x80,0x80,0xB0,0x90,0x90,0x60,0x00, + + 5, // 0x48 'H' + 0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x4A 'J' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0xA0,0x40,0x00, + + 5, // 0x4B 'K' + 0x00,0x90,0xA0,0xA0,0xC0,0xC0,0xA0,0xA0,0x90,0x00, + + 5, // 0x4C 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF0,0x00, + + 5, // 0x4D 'M' + 0x00,0x90,0x90,0xF0,0xF0,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x4E 'N' + 0x00,0x90,0x90,0xD0,0xD0,0xB0,0xB0,0x90,0x90,0x00, + + 5, // 0x4F 'O' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x50 'P' + 0x00,0xE0,0x90,0x90,0x90,0xE0,0x80,0x80,0x80,0x00, + + 5, // 0x51 'Q' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x30, + + 5, // 0x52 'R' + 0x00,0xE0,0x90,0x90,0x90,0xE0,0xA0,0x90,0x90,0x00, + + 5, // 0x53 'S' + 0x00,0x60,0x90,0x80,0x60,0x10,0x90,0x90,0x60,0x00, + + 5, // 0x54 'T' + 0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x55 'U' + 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x56 'V' + 0x00,0x90,0x90,0x90,0x50,0x50,0x50,0x20,0x20,0x00, + + 5, // 0x57 'W' + 0x00,0x90,0x90,0x90,0x90,0x90,0xF0,0xF0,0x90,0x00, + + 5, // 0x58 'X' + 0x00,0x90,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00, + + 5, // 0x59 'Y' + 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x5A 'Z' + 0x00,0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0xF0,0x00, + + 5, // 0x5B '[' + 0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60, + + 5, // 0x5C '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08, + + 5, // 0x5D ']' + 0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, + + 5, // 0x5E '^' + 0x00,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00, + + 5, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x61 'a' + 0x00,0x00,0x00,0x60,0x10,0x70,0x90,0x90,0x70,0x00, + + 5, // 0x62 'b' + 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x00,0x60,0x90,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x64 'd' + 0x00,0x10,0x10,0x70,0x90,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x65 'e' + 0x00,0x00,0x00,0x60,0x90,0x90,0xF0,0x80,0x70,0x00, + + 5, // 0x66 'f' + 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x67 'g' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0xE0, + + 5, // 0x68 'h' + 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x69 'i' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x6A 'j' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0xC0, + + 5, // 0x6B 'k' + 0x00,0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x90,0x00, + + 5, // 0x6C 'l' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x6D 'm' + 0x00,0x00,0x00,0x90,0xF0,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x6E 'n' + 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x6F 'o' + 0x00,0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x70 'p' + 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0xE0,0x80,0x80, + + 5, // 0x71 'q' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0x10, + + 5, // 0x72 'r' + 0x00,0x00,0x00,0xB0,0x50,0x40,0x40,0x40,0xE0,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x00,0x60,0x90,0x40,0x20,0x90,0x60,0x00, + + 5, // 0x74 't' + 0x00,0x40,0x40,0xE0,0x40,0x40,0x40,0x50,0x20,0x00, + + 5, // 0x75 'u' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x76 'v' + 0x00,0x00,0x00,0x90,0x90,0x50,0x50,0x20,0x20,0x00, + + 5, // 0x77 'w' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x00, + + 5, // 0x78 'x' + 0x00,0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x00, + + 5, // 0x79 'y' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x70,0x10,0xE0, + + 5, // 0x7A 'z' + 0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0xF0,0x00, + + 5, // 0x7B '{' + 0x30,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x30, + + 5, // 0x7C '|' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0xC0, + + 5, // 0x7E '~' + 0x00,0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x7F '' + 0x00,0x20,0x70,0xD8,0x88,0x88,0xF8,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs5x11_mono[] = + { + 11, 3, 32, 128-32, + 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, + 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, + 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, + 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, + 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, + 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, + 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 5, // 0x22 '"' + 0x00,0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x23 '#' + 0x00,0x50,0x50,0xF8,0x50,0x50,0x50,0xF8,0x50,0x50,0x00, + + 5, // 0x24 '$' + 0x00,0x40,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x20,0x00, + + 5, // 0x25 '%' + 0x00,0x00,0x90,0x90,0x20,0x20,0x40,0x40,0x90,0x90,0x00, + + 5, // 0x26 '&' + 0x00,0x40,0xA0,0xA0,0x40,0xA8,0x90,0x90,0x68,0x00,0x00, + + 5, // 0x27 ''' + 0x00,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 5, // 0x29 ')' + 0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + + 5, // 0x2A '*' + 0x00,0x00,0x90,0x60,0xF0,0x60,0x90,0x00,0x00,0x00,0x00, + + 5, // 0x2B '+' + 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x40,0x80, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 5, // 0x2F '/' + 0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, + + 5, // 0x30 '0' + 0x00,0x70,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00,0x00, + + 5, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x32 '2' + 0x00,0x60,0x90,0x90,0x10,0x20,0x40,0x80,0xF0,0x00,0x00, + + 5, // 0x33 '3' + 0x00,0x60,0x90,0x10,0x60,0x10,0x10,0x90,0x60,0x00,0x00, + + 5, // 0x34 '4' + 0x00,0x10,0x30,0x50,0x50,0x90,0xF8,0x10,0x10,0x00,0x00, + + 5, // 0x35 '5' + 0x00,0xF0,0x80,0xE0,0x90,0x10,0x10,0x90,0x60,0x00,0x00, + + 5, // 0x36 '6' + 0x00,0x60,0x90,0x80,0xE0,0x90,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x37 '7' + 0x00,0xF0,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00,0x00, + + 5, // 0x38 '8' + 0x00,0x60,0x90,0x90,0x60,0x90,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x39 '9' + 0x00,0x60,0x90,0x90,0x90,0x70,0x10,0x90,0x60,0x00,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x40,0x80, + + 5, // 0x3C '<' + 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00, + + 5, // 0x3D '=' + 0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0x00, + + 5, // 0x3E '>' + 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00, + + 5, // 0x3F '?' + 0x00,0x60,0x90,0x10,0x10,0x20,0x40,0x00,0x40,0x00,0x00, + + 5, // 0x40 '@' + 0x00,0x60,0x90,0x90,0xB0,0xB0,0x80,0x80,0x70,0x00,0x00, + + 5, // 0x41 'A' + 0x00,0x60,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x42 'B' + 0x00,0xE0,0x90,0x90,0xE0,0x90,0x90,0x90,0xE0,0x00,0x00, + + 5, // 0x43 'C' + 0x00,0x60,0x90,0x80,0x80,0x80,0x80,0x90,0x60,0x00,0x00, + + 5, // 0x44 'D' + 0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00,0x00, + + 5, // 0x45 'E' + 0x00,0xF0,0x80,0x80,0xE0,0x80,0x80,0x80,0xF0,0x00,0x00, + + 5, // 0x46 'F' + 0x00,0xF0,0x80,0x80,0xE0,0x80,0x80,0x80,0x80,0x00,0x00, + + 5, // 0x47 'G' + 0x00,0x60,0x90,0x80,0x80,0xB0,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x48 'H' + 0x00,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x4A 'J' + 0x00,0x70,0x20,0x20,0x20,0x20,0xA0,0xA0,0x40,0x00,0x00, + + 5, // 0x4B 'K' + 0x00,0x90,0xA0,0xA0,0xC0,0xA0,0xA0,0x90,0x90,0x00,0x00, + + 5, // 0x4C 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF0,0x00,0x00, + + 5, // 0x4D 'M' + 0x00,0x90,0xF0,0xF0,0x90,0x90,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x4E 'N' + 0x00,0x90,0x90,0xD0,0xD0,0xB0,0xB0,0x90,0x90,0x00,0x00, + + 5, // 0x4F 'O' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x50 'P' + 0x00,0xE0,0x90,0x90,0x90,0xE0,0x80,0x80,0x80,0x00,0x00, + + 5, // 0x51 'Q' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x30,0x00, + + 5, // 0x52 'R' + 0x00,0xE0,0x90,0x90,0x90,0xE0,0xA0,0x90,0x90,0x00,0x00, + + 5, // 0x53 'S' + 0x00,0x60,0x90,0x80,0x60,0x10,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x54 'T' + 0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 5, // 0x55 'U' + 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x56 'V' + 0x00,0x90,0x90,0x90,0x50,0x50,0x50,0x20,0x20,0x00,0x00, + + 5, // 0x57 'W' + 0x00,0x90,0x90,0x90,0x90,0x90,0xF0,0xF0,0x90,0x00,0x00, + + 5, // 0x58 'X' + 0x00,0x90,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x59 'Y' + 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00,0x00, + + 5, // 0x5A 'Z' + 0x00,0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0xF0,0x00,0x00, + + 5, // 0x5B '[' + 0x00,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60, + + 5, // 0x5C '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, + + 5, // 0x5D ']' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, + + 5, // 0x5E '^' + 0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00, + + 5, // 0x60 '`' + 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x61 'a' + 0x00,0x00,0x00,0x60,0x10,0x70,0x90,0x90,0x70,0x00,0x00, + + 5, // 0x62 'b' + 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0xE0,0x00,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x00,0x60,0x90,0x80,0x80,0x90,0x60,0x00,0x00, + + 5, // 0x64 'd' + 0x00,0x10,0x10,0x70,0x90,0x90,0x90,0x90,0x70,0x00,0x00, + + 5, // 0x65 'e' + 0x00,0x00,0x00,0x60,0x90,0x90,0xF0,0x80,0x70,0x00,0x00, + + 5, // 0x66 'f' + 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 5, // 0x67 'g' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x90,0x70,0x10,0xE0, + + 5, // 0x68 'h' + 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x69 'i' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + + 5, // 0x6B 'k' + 0x00,0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x90,0x00,0x00, + + 5, // 0x6C 'l' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x6D 'm' + 0x00,0x00,0x00,0x90,0xF0,0x90,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x6E 'n' + 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x6F 'o' + 0x00,0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x70 'p' + 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0x80,0x80, + + 5, // 0x71 'q' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x90,0x70,0x10,0x10, + + 5, // 0x72 'r' + 0x00,0x00,0x00,0xA0,0x50,0x40,0x40,0x40,0xE0,0x00,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x00,0x60,0x90,0x40,0x20,0x90,0x60,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x30,0x00,0x00, + + 5, // 0x75 'u' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x00,0x00, + + 5, // 0x76 'v' + 0x00,0x00,0x00,0x90,0x90,0x50,0x50,0x20,0x20,0x00,0x00, + + 5, // 0x77 'w' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x00,0x00, + + 5, // 0x78 'x' + 0x00,0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x00,0x00, + + 5, // 0x79 'y' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x10,0xE0, + + 5, // 0x7A 'z' + 0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0xF0,0x00,0x00, + + 5, // 0x7B '{' + 0x30,0x40,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x30, + + 5, // 0x7C '|' + 0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0xC0, + + 5, // 0x7E '~' + 0x00,0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x7F '' + 0x00,0x20,0x70,0xD8,0x88,0x88,0xF8,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs6x10_mono[] = + { + 10, 3, 32, 128-32, + 0x00,0x00,0x0B,0x00,0x16,0x00,0x21,0x00,0x2C,0x00,0x37,0x00,0x42,0x00,0x4D,0x00,0x58,0x00, + 0x63,0x00,0x6E,0x00,0x79,0x00,0x84,0x00,0x8F,0x00,0x9A,0x00,0xA5,0x00,0xB0,0x00,0xBB,0x00, + 0xC6,0x00,0xD1,0x00,0xDC,0x00,0xE7,0x00,0xF2,0x00,0xFD,0x00,0x08,0x01,0x13,0x01,0x1E,0x01, + 0x29,0x01,0x34,0x01,0x3F,0x01,0x4A,0x01,0x55,0x01,0x60,0x01,0x6B,0x01,0x76,0x01,0x81,0x01, + 0x8C,0x01,0x97,0x01,0xA2,0x01,0xAD,0x01,0xB8,0x01,0xC3,0x01,0xCE,0x01,0xD9,0x01,0xE4,0x01, + 0xEF,0x01,0xFA,0x01,0x05,0x02,0x10,0x02,0x1B,0x02,0x26,0x02,0x31,0x02,0x3C,0x02,0x47,0x02, + 0x52,0x02,0x5D,0x02,0x68,0x02,0x73,0x02,0x7E,0x02,0x89,0x02,0x94,0x02,0x9F,0x02,0xAA,0x02, + 0xB5,0x02,0xC0,0x02,0xCB,0x02,0xD6,0x02,0xE1,0x02,0xEC,0x02,0xF7,0x02,0x02,0x03,0x0D,0x03, + 0x18,0x03,0x23,0x03,0x2E,0x03,0x39,0x03,0x44,0x03,0x4F,0x03,0x5A,0x03,0x65,0x03,0x70,0x03, + 0x7B,0x03,0x86,0x03,0x91,0x03,0x9C,0x03,0xA7,0x03,0xB2,0x03,0xBD,0x03,0xC8,0x03,0xD3,0x03, + 0xDE,0x03,0xE9,0x03,0xF4,0x03,0xFF,0x03,0x0A,0x04,0x15,0x04, + + 6, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00, + + 6, // 0x22 '"' + 0x00,0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x28,0x28,0x7C,0x28,0x28,0x7C,0x28,0x28,0x00, + + 6, // 0x24 '$' + 0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00, + + 6, // 0x25 '%' + 0x00,0x08,0xC8,0xD0,0x10,0x20,0x2C,0x4C,0x40,0x00, + + 6, // 0x26 '&' + 0x00,0x20,0x50,0x50,0x24,0x54,0x48,0x34,0x00,0x00, + + 6, // 0x27 ''' + 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x08,0x10,0x10,0x20,0x20,0x20,0x10,0x10,0x08,0x00, + + 6, // 0x29 ')' + 0x20,0x10,0x10,0x08,0x08,0x08,0x10,0x10,0x20,0x00, + + 6, // 0x2A '*' + 0x00,0x00,0x28,0x7C,0x38,0x7C,0x28,0x00,0x00,0x00, + + 6, // 0x2B '+' + 0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 6, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 6, // 0x2F '/' + 0x00,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00, + + 6, // 0x30 '0' + 0x00,0x38,0x44,0x4C,0x54,0x64,0x44,0x38,0x00,0x00, + + 6, // 0x31 '1' + 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x32 '2' + 0x00,0x38,0x44,0x04,0x18,0x20,0x40,0x7C,0x00,0x00, + + 6, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x38,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x48,0x7C,0x08,0x08,0x00,0x00, + + 6, // 0x35 '5' + 0x00,0x7C,0x40,0x40,0x78,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x36 '6' + 0x00,0x38,0x40,0x40,0x78,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x10,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x3C,0x04,0x04,0x38,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x20,0x40, + + 6, // 0x3C '<' + 0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, + + 6, // 0x3D '=' + 0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, + + 6, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x18,0x10,0x00,0x10,0x00,0x00, + + 6, // 0x40 '@' + 0x00,0x38,0x44,0x5C,0x54,0x5C,0x40,0x38,0x00,0x00, + + 6, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x00,0x00, + + 6, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 6, // 0x44 'D' + 0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x4C,0x44,0x44,0x3C,0x00,0x00, + + 6, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, + + 6, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x4D 'M' + 0x00,0x44,0x6C,0x54,0x54,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x4E 'N' + 0x00,0x44,0x44,0x64,0x54,0x4C,0x44,0x44,0x00,0x00, + + 6, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, + + 6, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, + + 6, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x00,0x00, + + 6, // 0x57 'W' + 0x00,0x44,0x44,0x54,0x54,0x54,0x54,0x28,0x00,0x00, + + 6, // 0x58 'X' + 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 6, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x5A 'Z' + 0x00,0x78,0x08,0x10,0x20,0x40,0x40,0x78,0x00,0x00, + + 6, // 0x5B '[' + 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + + 6, // 0x5C '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, + + 6, // 0x5D ']' + 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, + + 6, // 0x5E '^' + 0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, + + 6, // 0x60 '`' + 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x3C,0x00,0x00, + + 6, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x3C,0x00,0x00, + + 6, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x78,0x40,0x3C,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x0C,0x10,0x10,0x38,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x38, + + 6, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x69 'i' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x6A 'j' + 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x48,0x30, + + 6, // 0x6B 'k' + 0x00,0x40,0x40,0x48,0x50,0x60,0x50,0x48,0x00,0x00, + + 6, // 0x6C 'l' + 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x6D 'm' + 0x00,0x00,0x00,0x68,0x54,0x54,0x44,0x44,0x00,0x00, + + 6, // 0x6E 'n' + 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x04, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x38,0x40,0x38,0x04,0x78,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x10,0x10,0x38,0x10,0x10,0x14,0x08,0x00,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x10,0x00,0x00, + + 6, // 0x77 'w' + 0x00,0x00,0x00,0x44,0x44,0x54,0x7C,0x28,0x00,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x48,0x48,0x30,0x48,0x48,0x00,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x3C,0x04,0x38, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x78,0x08,0x30,0x40,0x78,0x00,0x00, + + 6, // 0x7B '{' + 0x18,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x18,0x00, + + 6, // 0x7C '|' + 0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x10,0x00, + + 6, // 0x7D '}' + 0x60,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x60,0x00, + + 6, // 0x7E '~' + 0x00,0x48,0xA8,0x90,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs6x11_mono[] = + { + 11, 3, 32, 128-32, + 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, + 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, + 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, + 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, + 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, + 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, + 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, + + 6, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 6, // 0x22 '"' + 0x00,0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x28,0x28,0x7C,0x28,0x28,0x7C,0x28,0x28,0x00,0x00, + + 6, // 0x24 '$' + 0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00, + + 6, // 0x25 '%' + 0x00,0x68,0xA8,0xD0,0x10,0x20,0x2C,0x54,0x58,0x00,0x00, + + 6, // 0x26 '&' + 0x00,0x20,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00,0x00, + + 6, // 0x27 ''' + 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x00, + + 6, // 0x29 ')' + 0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x00, + + 6, // 0x2A '*' + 0x00,0x00,0x28,0x7C,0x38,0x7C,0x28,0x00,0x00,0x00,0x00, + + 6, // 0x2B '+' + 0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 6, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 6, // 0x2F '/' + 0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00, + + 6, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x31 '1' + 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x32 '2' + 0x00,0x38,0x44,0x44,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 6, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00,0x00, + + 6, // 0x35 '5' + 0x00,0x7C,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x00,0x00, + + 6, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x20,0x40, + + 6, // 0x3C '<' + 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, + + 6, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, + + 6, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, + + 6, // 0x40 '@' + 0x00,0x38,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00, + + 6, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 6, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x4C,0x34,0x00,0x00, + + 6, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, + + 6, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x44,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x4D 'M' + 0x00,0x44,0x6C,0x54,0x54,0x54,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x4E 'N' + 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x00,0x00, + + 6, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, + + 6, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, + + 6, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, + + 6, // 0x57 'W' + 0x00,0x44,0x44,0x54,0x54,0x54,0x54,0x54,0x28,0x00,0x00, + + 6, // 0x58 'X' + 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x5A 'Z' + 0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x5B '[' + 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + + 6, // 0x5C '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, + + 6, // 0x5D ']' + 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, + + 6, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, + + 6, // 0x60 '`' + 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x3C,0x00,0x00, + + 6, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00, + + 6, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x0C,0x10,0x38,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x78, + + 6, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x69 'i' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x6A 'j' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + + 6, // 0x6B 'k' + 0x00,0x40,0x40,0x4C,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 6, // 0x6C 'l' + 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x6D 'm' + 0x00,0x00,0x00,0x68,0x54,0x54,0x54,0x44,0x44,0x00,0x00, + + 6, // 0x6E 'n' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x30,0x08,0x44,0x38,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x18,0x00,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, + + 6, // 0x77 'w' + 0x00,0x00,0x00,0x44,0x44,0x44,0x54,0x7C,0x28,0x00,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3C,0x08,0x70, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 6, // 0x7B '{' + 0x18,0x20,0x20,0x20,0xC0,0xC0,0x20,0x20,0x20,0x18,0x00, + + 6, // 0x7C '|' + 0x00,0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x10,0x00, + + 6, // 0x7D '}' + 0x60,0x10,0x10,0x10,0x0C,0x0C,0x10,0x10,0x10,0x60,0x00, + + 6, // 0x7E '~' + 0x00,0x24,0x54,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs7x12_mono_high[] = + { + 12, 3, 32, 128-32, + 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4E,0x00,0x5B,0x00,0x68,0x00, + 0x75,0x00,0x82,0x00,0x8F,0x00,0x9C,0x00,0xA9,0x00,0xB6,0x00,0xC3,0x00,0xD0,0x00,0xDD,0x00, + 0xEA,0x00,0xF7,0x00,0x04,0x01,0x11,0x01,0x1E,0x01,0x2B,0x01,0x38,0x01,0x45,0x01,0x52,0x01, + 0x5F,0x01,0x6C,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xA0,0x01,0xAD,0x01,0xBA,0x01,0xC7,0x01, + 0xD4,0x01,0xE1,0x01,0xEE,0x01,0xFB,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2F,0x02,0x3C,0x02, + 0x49,0x02,0x56,0x02,0x63,0x02,0x70,0x02,0x7D,0x02,0x8A,0x02,0x97,0x02,0xA4,0x02,0xB1,0x02, + 0xBE,0x02,0xCB,0x02,0xD8,0x02,0xE5,0x02,0xF2,0x02,0xFF,0x02,0x0C,0x03,0x19,0x03,0x26,0x03, + 0x33,0x03,0x40,0x03,0x4D,0x03,0x5A,0x03,0x67,0x03,0x74,0x03,0x81,0x03,0x8E,0x03,0x9B,0x03, + 0xA8,0x03,0xB5,0x03,0xC2,0x03,0xCF,0x03,0xDC,0x03,0xE9,0x03,0xF6,0x03,0x03,0x04,0x10,0x04, + 0x1D,0x04,0x2A,0x04,0x37,0x04,0x44,0x04,0x51,0x04,0x5E,0x04,0x6B,0x04,0x78,0x04,0x85,0x04, + 0x92,0x04,0x9F,0x04,0xAC,0x04,0xB9,0x04,0xC6,0x04,0xD3,0x04, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x22 '"' + 0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x24,0x24,0x24,0x7E,0x24,0x24,0x24,0x7E,0x24,0x24,0x24,0x00, + + 7, // 0x24 '$' + 0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10,0x00, + + 7, // 0x25 '%' + 0x32,0x54,0x64,0x08,0x08,0x10,0x10,0x26,0x2A,0x4C,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x20,0x50,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00,0x00, + + 7, // 0x27 ''' + 0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x00, + + 7, // 0x29 ')' + 0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x00, + + 7, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00, + + 7, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 7, // 0x2F '/' + 0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x28,0x48,0x48,0x7C,0x08,0x08,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x3A ':' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 7, // 0x3B ';' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x20,0x40, + + 7, // 0x3C '<' + 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, + + 7, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00, + + 7, // 0x3E '>' + 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, + + 7, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00,0x00, + + 7, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 7, // 0x4D 'M' + 0x00,0x44,0x6C,0x6C,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x4E 'N' + 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,0x00, + + 7, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x5A 'Z' + 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00, + + 7, // 0x5B '[' + 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + + 7, // 0x5C '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, + + 7, // 0x5D ']' + 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, + + 7, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x0C,0x10,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x78, + + 7, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x6A 'j' + 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x48,0x30, + + 7, // 0x6B 'k' + 0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 7, // 0x6C 'l' + 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x6D 'm' + 0x00,0x00,0x00,0x68,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x6E 'n' + 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x24,0x18,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x08,0x70, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 7, // 0x7B '{' + 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, + + 7, // 0x7C '|' + 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, + + 7, // 0x7D '}' + 0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x10,0x60,0x00, + + 7, // 0x7E '~' + 0x00,0x60,0x92,0x92,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs7x12_mono_low[] = + { + 12, 4, 32, 128-32, + 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4E,0x00,0x5B,0x00,0x68,0x00, + 0x75,0x00,0x82,0x00,0x8F,0x00,0x9C,0x00,0xA9,0x00,0xB6,0x00,0xC3,0x00,0xD0,0x00,0xDD,0x00, + 0xEA,0x00,0xF7,0x00,0x04,0x01,0x11,0x01,0x1E,0x01,0x2B,0x01,0x38,0x01,0x45,0x01,0x52,0x01, + 0x5F,0x01,0x6C,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xA0,0x01,0xAD,0x01,0xBA,0x01,0xC7,0x01, + 0xD4,0x01,0xE1,0x01,0xEE,0x01,0xFB,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2F,0x02,0x3C,0x02, + 0x49,0x02,0x56,0x02,0x63,0x02,0x70,0x02,0x7D,0x02,0x8A,0x02,0x97,0x02,0xA4,0x02,0xB1,0x02, + 0xBE,0x02,0xCB,0x02,0xD8,0x02,0xE5,0x02,0xF2,0x02,0xFF,0x02,0x0C,0x03,0x19,0x03,0x26,0x03, + 0x33,0x03,0x40,0x03,0x4D,0x03,0x5A,0x03,0x67,0x03,0x74,0x03,0x81,0x03,0x8E,0x03,0x9B,0x03, + 0xA8,0x03,0xB5,0x03,0xC2,0x03,0xCF,0x03,0xDC,0x03,0xE9,0x03,0xF6,0x03,0x03,0x04,0x10,0x04, + 0x1D,0x04,0x2A,0x04,0x37,0x04,0x44,0x04,0x51,0x04,0x5E,0x04,0x6B,0x04,0x78,0x04,0x85,0x04, + 0x92,0x04,0x9F,0x04,0xAC,0x04,0xB9,0x04,0xC6,0x04,0xD3,0x04, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x22 '"' + 0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00,0x00, + + 7, // 0x25 '%' + 0x34,0x54,0x68,0x08,0x10,0x10,0x20,0x2C,0x54,0x58,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x20,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00,0x00,0x00, + + 7, // 0x27 ''' + 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x00, + + 7, // 0x29 ')' + 0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x00, + + 7, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00, + + 7, // 0x2B '+' + 0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00,0x00, + + 7, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40,0x00, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x2F '/' + 0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x38,0x44,0x44,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x7C,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x00,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x3A ':' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x3B ';' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x20,0x40,0x00, + + 7, // 0x3C '<' + 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, + + 7, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00, + + 7, // 0x3E '>' + 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x38,0x44,0x44,0x5C,0x54,0x4C,0x40,0x38,0x00,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x4C,0x44,0x4C,0x34,0x00,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00,0x00, + + 7, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x00,0x00,0x00, + + 7, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x4D 'M' + 0x00,0x44,0x6C,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x4E 'N' + 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x00,0x00,0x00, + + 7, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0x44,0x44,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x5A 'Z' + 0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x5B '[' + 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + + 7, // 0x5C '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, + + 7, // 0x5D ']' + 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, + + 7, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x3C,0x00,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x3C,0x00,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x7C,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x0C,0x10,0x38,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x44,0x38, + + 7, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x6A 'j' + 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30, + + 7, // 0x6B 'k' + 0x00,0x40,0x40,0x4C,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, + + 7, // 0x6C 'l' + 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x6D 'm' + 0x00,0x00,0x00,0x68,0x54,0x54,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x6E 'n' + 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04,0x04, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x30,0x08,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x24,0x18,0x00,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x08,0x70, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x7B '{' + 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, + + 7, // 0x7C '|' + 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, + + 7, // 0x7D '}' + 0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x10,0x60,0x00, + + 7, // 0x7E '~' + 0x00,0x24,0x54,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana12[] = + { + 12, 3, 32, 128-32, + 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x5A,0x00,0x67,0x00,0x74,0x00, + 0x81,0x00,0x8E,0x00,0x9B,0x00,0xA8,0x00,0xB5,0x00,0xC2,0x00,0xCF,0x00,0xDC,0x00,0xE9,0x00, + 0xF6,0x00,0x03,0x01,0x10,0x01,0x1D,0x01,0x2A,0x01,0x37,0x01,0x44,0x01,0x51,0x01,0x5E,0x01, + 0x6B,0x01,0x78,0x01,0x85,0x01,0x92,0x01,0x9F,0x01,0xAC,0x01,0xC5,0x01,0xD2,0x01,0xDF,0x01, + 0xEC,0x01,0xF9,0x01,0x06,0x02,0x13,0x02,0x20,0x02,0x2D,0x02,0x3A,0x02,0x47,0x02,0x54,0x02, + 0x61,0x02,0x7A,0x02,0x87,0x02,0xA0,0x02,0xAD,0x02,0xC6,0x02,0xD3,0x02,0xE0,0x02,0xED,0x02, + 0xFA,0x02,0x07,0x03,0x20,0x03,0x2D,0x03,0x3A,0x03,0x47,0x03,0x54,0x03,0x61,0x03,0x6E,0x03, + 0x7B,0x03,0x88,0x03,0x95,0x03,0xA2,0x03,0xAF,0x03,0xBC,0x03,0xC9,0x03,0xD6,0x03,0xE3,0x03, + 0xF0,0x03,0xFD,0x03,0x0A,0x04,0x17,0x04,0x24,0x04,0x31,0x04,0x4A,0x04,0x57,0x04,0x64,0x04, + 0x71,0x04,0x7E,0x04,0x8B,0x04,0x98,0x04,0xA5,0x04,0xB2,0x04,0xBF,0x04,0xCC,0x04,0xD9,0x04, + 0xE6,0x04,0xF3,0x04,0x00,0x05,0x0D,0x05,0x1A,0x05,0x27,0x05, + + 3, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 5, // 0x22 '"' + 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x28,0x7C,0x28,0x7C,0x28,0x00,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x00,0x10,0x10,0x3C,0x50,0x30,0x18,0x14,0x78,0x10,0x10, + + 11, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x4A,0x00,0x4A,0x00,0x35,0x80,0x0A,0x40,0x0A,0x40,0x11,0x80,0x00,0x00,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x00,0x00,0x30,0x48,0x48,0x32,0x4A,0x44,0x3A,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x28 '(' + 0x00,0x00,0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x10, + + 4, // 0x29 ')' + 0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x80, + + 7, // 0x2A '*' + 0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 3, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80,0x00, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x00, + + 4, // 0x2F '/' + 0x00,0x00,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x80,0x00, + + 7, // 0x30 '0' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x00,0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x20,0x7C,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x00,0x00,0x38,0x44,0x04,0x18,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x00,0x00,0x08,0x18,0x28,0x48,0x7C,0x08,0x08,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x00,0x00,0x7C,0x40,0x78,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x00,0x00,0x18,0x20,0x40,0x78,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x00,0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x00,0x00,0x38,0x44,0x44,0x3C,0x04,0x08,0x30,0x00,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x80,0x00, + + 7, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x04,0x18,0x60,0x18,0x04,0x00,0x00,0x00, + + 7, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x7C,0x00,0x00,0x00,0x00, + + 7, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x40,0x30,0x0C,0x30,0x40,0x00,0x00,0x00, + + 6, // 0x3F '?' + 0x00,0x00,0x00,0x70,0x08,0x08,0x10,0x20,0x00,0x20,0x00,0x00, + + 10, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x4E,0x80,0x52,0x80,0x52,0x80,0x4D,0x00,0x20,0x00,0x1F,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x7E,0x42,0x42,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x00,0x00,0x70,0x48,0x48,0x78,0x44,0x44,0x78,0x00,0x00, + + 8, // 0x43 'C' + 0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x22,0x1C,0x00,0x00, + + 8, // 0x44 'D' + 0x00,0x00,0x00,0x78,0x44,0x42,0x42,0x42,0x44,0x78,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x00,0x00, + + 8, // 0x47 'G' + 0x00,0x00,0x00,0x1C,0x22,0x40,0x4E,0x42,0x22,0x1C,0x00,0x00, + + 8, // 0x48 'H' + 0x00,0x00,0x00,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x4A 'J' + 0x00,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0,0x00,0x00, + + 7, // 0x4B 'K' + 0x00,0x00,0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 9, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x55,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4E 'N' + 0x00,0x00,0x00,0x42,0x62,0x52,0x4A,0x46,0x42,0x42,0x00,0x00, + + 9, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x00,0x00, + + 9, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x04,0x00,0x03,0x00, + + 7, // 0x52 'R' + 0x00,0x00,0x00,0x78,0x44,0x44,0x78,0x50,0x48,0x44,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 8, // 0x55 'U' + 0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x00,0x42,0x42,0x42,0x24,0x24,0x18,0x18,0x00,0x00, + + 9, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x55,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x5A 'Z' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 4, // 0x5B '[' + 0x00,0x00,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60, + + 4, // 0x5C '\' + 0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x00, + + 4, // 0x5D ']' + 0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, + + 7, // 0x5E '^' + 0x00,0x00,0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, + + 6, // 0x60 '`' + 0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x30,0x08,0x38,0x48,0x38,0x00,0x00, + + 6, // 0x62 'b' + 0x00,0x00,0x40,0x40,0x40,0x70,0x48,0x48,0x48,0x70,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x40,0x40,0x38,0x00,0x00, + + 6, // 0x64 'd' + 0x00,0x00,0x08,0x08,0x08,0x38,0x48,0x48,0x48,0x38,0x00,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x78,0x40,0x38,0x00,0x00, + + 4, // 0x66 'f' + 0x00,0x00,0x30,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x30, + + 6, // 0x68 'h' + 0x00,0x00,0x40,0x40,0x40,0x70,0x48,0x48,0x48,0x48,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 3, // 0x6A 'j' + 0x00,0x00,0x00,0x40,0x00,0xC0,0x40,0x40,0x40,0x40,0x40,0x80, + + 6, // 0x6B 'k' + 0x00,0x00,0x40,0x40,0x40,0x48,0x50,0x60,0x50,0x48,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 9, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x70,0x48,0x48,0x48,0x48,0x00,0x00, + + 6, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x70,0x48,0x48,0x48,0x70,0x40,0x40, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x08, + + 4, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x50,0x60,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x30,0x08,0x70,0x00,0x00, + + 4, // 0x74 't' + 0x00,0x00,0x00,0x00,0x40,0xF0,0x40,0x40,0x40,0x30,0x00,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x48,0x38,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x30,0x30,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x44,0x54,0x54,0x28,0x28,0x00,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x30,0x48,0x48,0x00,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x30,0x10,0x20,0x20, + + 5, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x70,0x10,0x20,0x40,0x70,0x00,0x00, + + 6, // 0x7B '{' + 0x00,0x00,0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x18, + + 5, // 0x7C '|' + 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + + 6, // 0x7D '}' + 0x00,0x00,0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x60, + + 7, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x58,0x00,0x00,0x00,0x00, + + 9, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana12_bold[] = + { + 12, 3, 32, 128-32, + 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x5A,0x00,0x67,0x00,0x74,0x00, + 0x81,0x00,0x8E,0x00,0x9B,0x00,0xA8,0x00,0xB5,0x00,0xC2,0x00,0xCF,0x00,0xDC,0x00,0xE9,0x00, + 0xF6,0x00,0x03,0x01,0x10,0x01,0x1D,0x01,0x2A,0x01,0x37,0x01,0x44,0x01,0x51,0x01,0x5E,0x01, + 0x6B,0x01,0x78,0x01,0x85,0x01,0x92,0x01,0x9F,0x01,0xAC,0x01,0xC5,0x01,0xD2,0x01,0xDF,0x01, + 0xEC,0x01,0xF9,0x01,0x06,0x02,0x13,0x02,0x20,0x02,0x2D,0x02,0x3A,0x02,0x47,0x02,0x54,0x02, + 0x61,0x02,0x6E,0x02,0x7B,0x02,0x88,0x02,0x95,0x02,0xA2,0x02,0xAF,0x02,0xBC,0x02,0xC9,0x02, + 0xD6,0x02,0xE3,0x02,0xFC,0x02,0x09,0x03,0x16,0x03,0x23,0x03,0x30,0x03,0x3D,0x03,0x4A,0x03, + 0x57,0x03,0x64,0x03,0x71,0x03,0x7E,0x03,0x8B,0x03,0x98,0x03,0xA5,0x03,0xB2,0x03,0xBF,0x03, + 0xCC,0x03,0xD9,0x03,0xE6,0x03,0xF3,0x03,0x00,0x04,0x0D,0x04,0x26,0x04,0x33,0x04,0x40,0x04, + 0x4D,0x04,0x5A,0x04,0x67,0x04,0x74,0x04,0x81,0x04,0x8E,0x04,0x9B,0x04,0xB4,0x04,0xC1,0x04, + 0xCE,0x04,0xDB,0x04,0xE8,0x04,0xF5,0x04,0x02,0x05,0x0F,0x05, + + 3, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x00,0x60,0x00,0x00, + + 5, // 0x22 '"' + 0x00,0x00,0xD8,0xD8,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x23 '#' + 0x00,0x00,0x00,0x14,0x14,0x7E,0x28,0xFC,0x50,0x50,0x00,0x00, + + 6, // 0x24 '$' + 0x00,0x00,0x20,0x20,0x70,0xE8,0xE0,0x38,0xB8,0x70,0x20,0x20, + + 11, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x00,0x94,0x00,0x94,0x00,0x69,0x80,0x0A,0x40,0x0A,0x40,0x11,0x80,0x00,0x00,0x00,0x00, + + 8, // 0x26 '&' + 0x00,0x00,0x00,0x70,0xD8,0xD8,0x76,0xDC,0xCC,0x76,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x00,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x00,0x00,0x30,0x60,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x60,0x30, + + 5, // 0x29 ')' + 0x00,0x00,0xC0,0x60,0x30,0x30,0x30,0x30,0x30,0x30,0x60,0xC0, + + 6, // 0x2A '*' + 0x00,0x00,0x20,0xA8,0x70,0xA8,0x20,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 3, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x80,0x00, + + 4, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00, + + 6, // 0x2F '/' + 0x00,0x00,0x08,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0x80,0x00, + + 6, // 0x30 '0' + 0x00,0x00,0x00,0x70,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00, + + 6, // 0x31 '1' + 0x00,0x00,0x00,0x30,0x70,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 6, // 0x32 '2' + 0x00,0x00,0x00,0x70,0x98,0x18,0x30,0x60,0xC0,0xF8,0x00,0x00, + + 6, // 0x33 '3' + 0x00,0x00,0x00,0x70,0x98,0x18,0x70,0x18,0x98,0x70,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x00,0x00,0x18,0x38,0x58,0x98,0xFC,0x18,0x18,0x00,0x00, + + 6, // 0x35 '5' + 0x00,0x00,0x00,0xF8,0xC0,0xF0,0x18,0x18,0x98,0x70,0x00,0x00, + + 6, // 0x36 '6' + 0x00,0x00,0x00,0x70,0xC0,0xF0,0xD8,0xD8,0xD8,0x70,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0x00,0x00,0xF8,0x18,0x30,0x30,0x60,0x60,0xC0,0x00,0x00, + + 6, // 0x38 '8' + 0x00,0x00,0x00,0x70,0xD8,0xD8,0x70,0xD8,0xD8,0x70,0x00,0x00, + + 6, // 0x39 '9' + 0x00,0x00,0x00,0x70,0xD8,0xD8,0xD8,0x78,0x18,0x70,0x00,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x00,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x40,0x00, + + 8, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x04,0x18,0x60,0x60,0x18,0x04,0x00,0x00, + + 8, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x7C,0x00,0x00,0x00,0x00, + + 8, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x40,0x30,0x0C,0x0C,0x30,0x40,0x00,0x00, + + 6, // 0x3F '?' + 0x00,0x00,0x00,0xF0,0x18,0x18,0x30,0x60,0x00,0x60,0x00,0x00, + + 9, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x9D,0x00,0xA5,0x00,0xA5,0x00,0x9E,0x00,0x40,0x00,0x3C,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x00,0x38,0x38,0x6C,0x6C,0x7C,0xC6,0xC6,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xF8,0xCC,0xCC,0xF8,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x00,0x00,0x70,0xC8,0xC0,0xC0,0xC0,0xC8,0x70,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xCC,0xCC,0xCC,0xF8,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0x00,0x00,0xF8,0xC0,0xC0,0xF8,0xC0,0xC0,0xF8,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x00,0x00,0xF8,0xC0,0xC0,0xF8,0xC0,0xC0,0xC0,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x00,0x00,0x78,0xC4,0xC0,0xC0,0xDC,0xCC,0x7C,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x00,0x00,0xCC,0xCC,0xCC,0xFC,0xCC,0xCC,0xCC,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0xF0,0x00,0x00, + + 5, // 0x4A 'J' + 0x00,0x00,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0xE0,0x00,0x00, + + 7, // 0x4B 'K' + 0x00,0x00,0x00,0xCC,0xD8,0xF0,0xE0,0xF0,0xD8,0xCC,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xF8,0x00,0x00, + + 8, // 0x4D 'M' + 0x00,0x00,0x00,0x82,0xC6,0xEE,0xB6,0xB6,0x86,0x86,0x00,0x00, + + 7, // 0x4E 'N' + 0x00,0x00,0x00,0x84,0xC4,0xE4,0xB4,0x9C,0x8C,0x84,0x00,0x00, + + 8, // 0x4F 'O' + 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xCC,0xF8,0xC0,0xC0,0x00,0x00, + + 8, // 0x51 'Q' + 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x18,0x0E, + + 7, // 0x52 'R' + 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xF8,0xD8,0xCC,0xC6,0x00,0x00, + + 6, // 0x53 'S' + 0x00,0x00,0x00,0x70,0xC8,0xC0,0x70,0x18,0x98,0x70,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0x00,0x00,0xFC,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x00,0x00,0xCC,0xCC,0x78,0x78,0x78,0x30,0x30,0x00,0x00, + + 11, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xC0,0xCC,0xC0,0x6D,0x80,0x6D,0x80,0x73,0x80,0x33,0x00,0x33,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x00,0x00,0xCC,0xCC,0x78,0x30,0x78,0xCC,0xCC,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0x00,0xCC,0xCC,0x78,0x30,0x30,0x30,0x30,0x00,0x00, + + 6, // 0x5A 'Z' + 0x00,0x00,0x00,0xF8,0x18,0x30,0x60,0xC0,0xC0,0xF8,0x00,0x00, + + 5, // 0x5B '[' + 0x00,0x00,0x70,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x70, + + 6, // 0x5C '\' + 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x10,0x08,0x08,0x00, + + 5, // 0x5D ']' + 0x00,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x70, + + 8, // 0x5E '^' + 0x00,0x00,0x00,0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, + + 6, // 0x60 '`' + 0x00,0x00,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x70,0x18,0x78,0xD8,0x78,0x00,0x00, + + 6, // 0x62 'b' + 0x00,0x00,0xC0,0xC0,0xC0,0xF0,0xD8,0xD8,0xD8,0xF0,0x00,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x70,0xC0,0xC0,0xC0,0x70,0x00,0x00, + + 6, // 0x64 'd' + 0x00,0x00,0x18,0x18,0x18,0x78,0xD8,0xD8,0xD8,0x78,0x00,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x70,0xD8,0xF8,0xC0,0x78,0x00,0x00, + + 5, // 0x66 'f' + 0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x00,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x78,0xD8,0xD8,0xD8,0x78,0x18,0x70, + + 6, // 0x68 'h' + 0x00,0x00,0xC0,0xC0,0xC0,0xF0,0xD8,0xD8,0xD8,0xD8,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x00,0xC0,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00, + + 4, // 0x6A 'j' + 0x00,0x00,0x00,0x60,0x00,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0, + + 6, // 0x6B 'k' + 0x00,0x00,0xC0,0xC0,0xC0,0xD8,0xD8,0xF0,0xD8,0xD8,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00, + + 9, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF6,0x00,0xDB,0x00,0xDB,0x00,0xDB,0x00,0xDB,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0xF0,0xD8,0xD8,0xD8,0xD8,0x00,0x00, + + 6, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x70,0xD8,0xD8,0xD8,0x70,0x00,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0xF0,0xD8,0xD8,0xD8,0xF0,0xC0,0xC0, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x78,0xD8,0xD8,0xD8,0x78,0x18,0x18, + + 4, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0xD0,0xE0,0xC0,0xC0,0xC0,0x00,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x70,0xC0,0xF0,0x30,0xE0,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x38,0x00,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0xD8,0xD8,0x78,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0xD8,0x70,0x70,0x00,0x00, + + 9, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0xDB,0x00,0xDB,0x00,0x66,0x00,0x66,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x70,0xD8,0xD8,0x00,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0xD8,0x70,0x70,0x30,0x60, + + 5, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0xF0,0x30,0x60,0xC0,0xF0,0x00,0x00, + + 6, // 0x7B '{' + 0x00,0x00,0x18,0x30,0x30,0x30,0xE0,0x30,0x30,0x30,0x30,0x18, + + 5, // 0x7C '|' + 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + + 6, // 0x7D '}' + 0x00,0x00,0xC0,0x60,0x60,0x60,0x38,0x60,0x60,0x60,0x60,0xC0, + + 8, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x92,0x8C,0x00,0x00,0x00, + + 9, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana13[] = + { + 13, 3, 32, 128-32, + 0x00,0x00,0x0E,0x00,0x1C,0x00,0x2A,0x00,0x45,0x00,0x53,0x00,0x6E,0x00,0x7C,0x00,0x8A,0x00, + 0x98,0x00,0xA6,0x00,0xB4,0x00,0xCF,0x00,0xDD,0x00,0xEB,0x00,0xF9,0x00,0x07,0x01,0x15,0x01, + 0x23,0x01,0x31,0x01,0x3F,0x01,0x4D,0x01,0x5B,0x01,0x69,0x01,0x77,0x01,0x85,0x01,0x93,0x01, + 0xA1,0x01,0xAF,0x01,0xCA,0x01,0xE5,0x01,0x00,0x02,0x0E,0x02,0x29,0x02,0x37,0x02,0x45,0x02, + 0x60,0x02,0x7B,0x02,0x89,0x02,0x97,0x02,0xB2,0x02,0xC0,0x02,0xCE,0x02,0xDC,0x02,0xEA,0x02, + 0xF8,0x02,0x13,0x03,0x21,0x03,0x3C,0x03,0x4A,0x03,0x65,0x03,0x73,0x03,0x81,0x03,0x8F,0x03, + 0x9D,0x03,0xAB,0x03,0xC6,0x03,0xD4,0x03,0xE2,0x03,0xF0,0x03,0xFE,0x03,0x0C,0x04,0x1A,0x04, + 0x35,0x04,0x43,0x04,0x51,0x04,0x5F,0x04,0x6D,0x04,0x7B,0x04,0x89,0x04,0x97,0x04,0xA5,0x04, + 0xB3,0x04,0xC1,0x04,0xCF,0x04,0xDD,0x04,0xEB,0x04,0xF9,0x04,0x14,0x05,0x22,0x05,0x30,0x05, + 0x3E,0x05,0x4C,0x05,0x5A,0x05,0x68,0x05,0x76,0x05,0x84,0x05,0x92,0x05,0xAD,0x05,0xBB,0x05, + 0xC9,0x05,0xD7,0x05,0xE5,0x05,0xF3,0x05,0x01,0x06,0x1C,0x06, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 5, // 0x22 '"' + 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x0A,0x00,0x3F,0x00,0x14,0x00,0x14,0x00,0x7E,0x00,0x28,0x00,0x28,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x00,0x10,0x10,0x3C,0x50,0x50,0x38,0x14,0x14,0x78,0x10,0x10, + + 12, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x49,0x00,0x4A,0x00,0x32,0x00,0x04,0xC0,0x05,0x20,0x09,0x20,0x08,0xC0,0x00,0x00,0x00,0x00, + + 8, // 0x26 '&' + 0x00,0x00,0x00,0x30,0x48,0x48,0x32,0x4A,0x44,0x46,0x39,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x00,0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 5, // 0x29 ')' + 0x00,0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + + 7, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00, + + 5, // 0x2F '/' + 0x00,0x00,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, + + 7, // 0x30 '0' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x00,0x00,0x38,0x44,0x04,0x18,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x00,0x00,0x08,0x18,0x28,0x48,0x88,0xFC,0x08,0x08,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x00,0x00,0x18,0x20,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x00,0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x08,0x30,0x00,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x20,0x00,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x20,0x20,0x40, + + 9, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3F '?' + 0x00,0x00,0x00,0x70,0x08,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00, + + 10, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x4E,0x80,0x52,0x80,0x52,0x80,0x52,0x80,0x4D,0x00,0x20,0x00,0x1E,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x24,0x7E,0x42,0x42,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x00,0x78,0x44,0x44,0x7C,0x42,0x42,0x42,0x7C,0x00,0x00, + + 9, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x00,0x00,0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, + + 9, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x47,0x00,0x41,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x48 'H' + 0x00,0x00,0x00,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x4A 'J' + 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0xE0,0x00,0x00, + + 8, // 0x4B 'K' + 0x00,0x00,0x00,0x42,0x44,0x48,0x50,0x70,0x48,0x44,0x42,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 9, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x55,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4E 'N' + 0x00,0x00,0x00,0x62,0x62,0x52,0x52,0x4A,0x4A,0x46,0x46,0x00,0x00, + + 9, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 9, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x04,0x00,0x03,0x00, + + 8, // 0x52 'R' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x42,0x00,0x00, + + 8, // 0x53 'S' + 0x00,0x00,0x00,0x3C,0x42,0x40,0x30,0x0C,0x02,0x42,0x3C,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 8, // 0x55 'U' + 0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x00,0x42,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x00,0x00, + + 11, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x58 'X' + 0x00,0x00,0x00,0x42,0x42,0x24,0x18,0x18,0x24,0x42,0x42,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0x00,0x82,0x44,0x28,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 8, // 0x5A 'Z' + 0x00,0x00,0x00,0x7E,0x02,0x04,0x08,0x10,0x20,0x40,0x7E,0x00,0x00, + + 5, // 0x5B '[' + 0x00,0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70, + + 5, // 0x5C '\' + 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, + + 5, // 0x5D ']' + 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70, + + 9, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, + + 7, // 0x60 '`' + 0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x00,0x04,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, + + 4, // 0x66 'f' + 0x00,0x00,0x30,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x38, + + 7, // 0x68 'h' + 0x00,0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 4, // 0x6A 'j' + 0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0xC0, + + 7, // 0x6B 'k' + 0x00,0x00,0x40,0x40,0x40,0x44,0x48,0x50,0x70,0x48,0x44,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 11, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7B,0x80,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x00,0x00,0x00,0x00, + + 7, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, + + 5, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x40,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x60,0x18,0x08,0x70,0x00,0x00, + + 4, // 0x74 't' + 0x00,0x00,0x00,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x30,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, + + 9, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x55,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x10,0x10,0x28,0x44,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x28,0x28,0x10,0x10,0x10,0x20, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x78,0x08,0x10,0x20,0x40,0x78,0x00,0x00, + + 7, // 0x7B '{' + 0x00,0x00,0x0C,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x0C, + + 5, // 0x7C '|' + 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + + 7, // 0x7D '}' + 0x00,0x00,0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x10,0x60, + + 9, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x49,0x00,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7F,0x80,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana13_bold[] = + { + 13, 3, 32, 128-32, + 0x00,0x00,0x0E,0x00,0x1C,0x00,0x2A,0x00,0x45,0x00,0x53,0x00,0x6E,0x00,0x89,0x00,0x97,0x00, + 0xA5,0x00,0xB3,0x00,0xC1,0x00,0xDC,0x00,0xEA,0x00,0xF8,0x00,0x06,0x01,0x14,0x01,0x22,0x01, + 0x30,0x01,0x3E,0x01,0x4C,0x01,0x5A,0x01,0x68,0x01,0x76,0x01,0x84,0x01,0x92,0x01,0xA0,0x01, + 0xAE,0x01,0xBC,0x01,0xD7,0x01,0xF2,0x01,0x0D,0x02,0x1B,0x02,0x36,0x02,0x51,0x02,0x5F,0x02, + 0x6D,0x02,0x88,0x02,0x96,0x02,0xA4,0x02,0xBF,0x02,0xDA,0x02,0xE8,0x02,0xF6,0x02,0x04,0x03, + 0x12,0x03,0x2D,0x03,0x48,0x03,0x63,0x03,0x71,0x03,0x8C,0x03,0x9A,0x03,0xA8,0x03,0xB6,0x03, + 0xD1,0x03,0xDF,0x03,0xFA,0x03,0x08,0x04,0x16,0x04,0x24,0x04,0x32,0x04,0x40,0x04,0x4E,0x04, + 0x69,0x04,0x77,0x04,0x85,0x04,0x93,0x04,0xA1,0x04,0xAF,0x04,0xBD,0x04,0xCB,0x04,0xD9,0x04, + 0xE7,0x04,0xF5,0x04,0x03,0x05,0x11,0x05,0x1F,0x05,0x2D,0x05,0x48,0x05,0x56,0x05,0x64,0x05, + 0x72,0x05,0x80,0x05,0x8E,0x05,0x9C,0x05,0xAA,0x05,0xB8,0x05,0xC6,0x05,0xE1,0x05,0xEF,0x05, + 0xFD,0x05,0x0B,0x06,0x19,0x06,0x27,0x06,0x35,0x06,0x50,0x06, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x60,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x0A,0x00,0x3F,0x00,0x14,0x00,0x14,0x00,0x7E,0x00,0x28,0x00,0x28,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x24 '$' + 0x00,0x00,0x08,0x08,0x3C,0x6A,0x68,0x3C,0x16,0x56,0x3C,0x10,0x10, + + 14, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x80,0x6C,0x80,0x6D,0x00,0x6D,0x70,0x3A,0xD8,0x02,0xD8,0x04,0xD8,0x04,0x70,0x00,0x00,0x00,0x00, + + 10, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x6C,0x00,0x6C,0x00,0x39,0x80,0x6D,0x00,0x66,0x00,0x63,0x00,0x3D,0x80,0x00,0x00,0x00,0x00, + + 4, // 0x27 ''' + 0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x00,0x00,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18, + + 6, // 0x29 ')' + 0x00,0x00,0x60,0x30,0x30,0x18,0x18,0x18,0x18,0x18,0x30,0x30,0x60, + + 8, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x40, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 8, // 0x2F '/' + 0x00,0x00,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x30,0x30,0x60,0x60, + + 8, // 0x30 '0' + 0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00, + + 8, // 0x31 '1' + 0x00,0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00, + + 8, // 0x32 '2' + 0x00,0x00,0x00,0x3C,0x66,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00, + + 8, // 0x33 '3' + 0x00,0x00,0x00,0x3C,0x66,0x06,0x1C,0x06,0x06,0x66,0x3C,0x00,0x00, + + 8, // 0x34 '4' + 0x00,0x00,0x00,0x04,0x0C,0x1C,0x2C,0x4C,0x7E,0x0C,0x0C,0x00,0x00, + + 8, // 0x35 '5' + 0x00,0x00,0x00,0x3E,0x30,0x30,0x3C,0x06,0x06,0x66,0x3C,0x00,0x00, + + 8, // 0x36 '6' + 0x00,0x00,0x00,0x1C,0x30,0x60,0x7C,0x66,0x66,0x66,0x3C,0x00,0x00, + + 8, // 0x37 '7' + 0x00,0x00,0x00,0x7E,0x06,0x0C,0x0C,0x18,0x18,0x30,0x30,0x00,0x00, + + 8, // 0x38 '8' + 0x00,0x00,0x00,0x3C,0x66,0x66,0x3C,0x66,0x66,0x66,0x3C,0x00,0x00, + + 8, // 0x39 '9' + 0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x60,0x40, + + 9, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x00,0x00,0x38,0x4C,0x0C,0x18,0x30,0x30,0x00,0x30,0x00,0x00, + + 11, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x4F,0x40,0x5B,0x40,0x5B,0x40,0x5B,0x40,0x4F,0x80,0x20,0x00,0x1F,0x00,0x00,0x00, + + 9, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x7F,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x00,0x7C,0x66,0x66,0x7C,0x66,0x66,0x66,0x7C,0x00,0x00, + + 8, // 0x43 'C' + 0x00,0x00,0x00,0x3C,0x62,0x60,0x60,0x60,0x60,0x62,0x3C,0x00,0x00, + + 9, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x66,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x66,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x00,0x7E,0x60,0x60,0x7E,0x60,0x60,0x60,0x7E,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x00,0x7E,0x60,0x60,0x7E,0x60,0x60,0x60,0x60,0x00,0x00, + + 9, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x61,0x00,0x60,0x00,0x60,0x00,0x67,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0xF0,0x00,0x00, + + 8, // 0x4B 'K' + 0x00,0x00,0x00,0x66,0x6C,0x78,0x70,0x70,0x78,0x6C,0x66,0x00,0x00, + + 7, // 0x4C 'L' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0x00, + + 10, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x80,0x71,0x80,0x7B,0x80,0x5D,0x80,0x49,0x80,0x41,0x80,0x41,0x80,0x41,0x80,0x00,0x00,0x00,0x00, + + 9, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x61,0x00,0x71,0x00,0x59,0x00,0x4D,0x00,0x47,0x00,0x43,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x00,0x00, + + 9, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x0C,0x00,0x07,0x00, + + 8, // 0x52 'R' + 0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x7C,0x6C,0x66,0x63,0x00,0x00, + + 8, // 0x53 'S' + 0x00,0x00,0x00,0x3C,0x62,0x60,0x7C,0x3E,0x06,0x46,0x3C,0x00,0x00, + + 8, // 0x54 'T' + 0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, + + 9, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x3C,0x18,0x18,0x00,0x00, + + 12, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,0x66,0x60,0x66,0x60,0x36,0xC0,0x3F,0xC0,0x39,0xC0,0x19,0x80,0x19,0x80,0x00,0x00,0x00,0x00, + + 8, // 0x58 'X' + 0x00,0x00,0x00,0x66,0x66,0x3C,0x18,0x18,0x3C,0x66,0x66,0x00,0x00, + + 8, // 0x59 'Y' + 0x00,0x00,0x00,0x66,0x66,0x3C,0x3C,0x18,0x18,0x18,0x18,0x00,0x00, + + 8, // 0x5A 'Z' + 0x00,0x00,0x00,0x7E,0x06,0x0E,0x1C,0x38,0x70,0x60,0x7E,0x00,0x00, + + 6, // 0x5B '[' + 0x00,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78, + + 8, // 0x5C '\' + 0x00,0x00,0x60,0x60,0x30,0x30,0x18,0x18,0x18,0x0C,0x0C,0x06,0x06, + + 6, // 0x5D ']' + 0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78, + + 10, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, + + 8, // 0x60 '`' + 0x00,0x00,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x60,0x60,0x60,0x60,0x3C,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x06,0x06,0x06,0x3E,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x7E,0x60,0x62,0x3C,0x00,0x00, + + 5, // 0x66 'f' + 0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C, + + 8, // 0x68 'h' + 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x00,0x00, + + 4, // 0x69 'i' + 0x00,0x00,0x00,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x00,0x00,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0xE0, + + 8, // 0x6B 'k' + 0x00,0x00,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x00,0x00, + + 4, // 0x6C 'l' + 0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 12, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7D,0xC0,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x00,0x00,0x00,0x00, + + 8, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x00,0x00, + + 8, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x7C,0x60,0x60, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x3E,0x06,0x06, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x6C,0x7C,0x60,0x60,0x60,0x60,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x60,0x78,0x3C,0x0C,0x78,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x38,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x18,0x00,0x00, + + 10, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x33,0x00,0x33,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x3C,0x3C,0x66,0x66,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x3C,0x3C,0x18,0x18,0x30,0x30, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x0C,0x18,0x30,0x60,0x7C,0x00,0x00, + + 8, // 0x7B '{' + 0x00,0x00,0x0E,0x18,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E, + + 6, // 0x7C '|' + 0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, + + 8, // 0x7D '}' + 0x00,0x00,0x70,0x18,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70, + + 9, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x49,0x00,0x49,0x00,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7F,0x80,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana14[] = + { + 14, 3, 32, 128-32, + 0x00,0x00,0x0F,0x00,0x1E,0x00,0x2D,0x00,0x4A,0x00,0x59,0x00,0x76,0x00,0x93,0x00,0xA2,0x00, + 0xB1,0x00,0xC0,0x00,0xCF,0x00,0xEC,0x00,0xFB,0x00,0x0A,0x01,0x19,0x01,0x28,0x01,0x37,0x01, + 0x46,0x01,0x55,0x01,0x64,0x01,0x73,0x01,0x82,0x01,0x91,0x01,0xA0,0x01,0xAF,0x01,0xBE,0x01, + 0xCD,0x01,0xDC,0x01,0xF9,0x01,0x16,0x02,0x33,0x02,0x42,0x02,0x5F,0x02,0x6E,0x02,0x7D,0x02, + 0x9A,0x02,0xB7,0x02,0xC6,0x02,0xD5,0x02,0xF2,0x02,0x0F,0x03,0x1E,0x03,0x2D,0x03,0x3C,0x03, + 0x4B,0x03,0x68,0x03,0x85,0x03,0xA2,0x03,0xB1,0x03,0xCE,0x03,0xDD,0x03,0xEC,0x03,0xFB,0x03, + 0x18,0x04,0x27,0x04,0x44,0x04,0x53,0x04,0x62,0x04,0x71,0x04,0x80,0x04,0x8F,0x04,0x9E,0x04, + 0xBB,0x04,0xCA,0x04,0xD9,0x04,0xE8,0x04,0xF7,0x04,0x06,0x05,0x15,0x05,0x24,0x05,0x33,0x05, + 0x42,0x05,0x51,0x05,0x60,0x05,0x6F,0x05,0x7E,0x05,0x8D,0x05,0xAA,0x05,0xB9,0x05,0xC8,0x05, + 0xD7,0x05,0xE6,0x05,0xF5,0x05,0x04,0x06,0x13,0x06,0x22,0x06,0x31,0x06,0x4E,0x06,0x5D,0x06, + 0x6C,0x06,0x7B,0x06,0x8A,0x06,0x99,0x06,0xA8,0x06,0xC5,0x06, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 6, // 0x22 '"' + 0x00,0x00,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x12,0x00,0x3F,0x80,0x12,0x00,0x12,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x24 '$' + 0x00,0x00,0x10,0x10,0x3E,0x50,0x50,0x30,0x1C,0x12,0x12,0x7C,0x10,0x10, + + 13, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x49,0x00,0x49,0x00,0x4A,0x00,0x32,0x60,0x02,0x90,0x04,0x90,0x04,0x90,0x08,0x60,0x00,0x00,0x00,0x00, + + 10, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x44,0x00,0x44,0x00,0x44,0x00,0x39,0x00,0x45,0x00,0x42,0x00,0x43,0x00,0x3C,0x80,0x00,0x00,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x00,0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 5, // 0x29 ')' + 0x00,0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + + 8, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00, + + 5, // 0x2F '/' + 0x00,0x00,0x08,0x08,0x10,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x40,0x80, + + 8, // 0x30 '0' + 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x31 '1' + 0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00, + + 8, // 0x32 '2' + 0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x20,0x40,0x7E,0x00,0x00, + + 8, // 0x33 '3' + 0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x1C,0x02,0x02,0x42,0x3C,0x00,0x00, + + 8, // 0x34 '4' + 0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x44,0x7F,0x04,0x04,0x04,0x00,0x00, + + 8, // 0x35 '5' + 0x00,0x00,0x00,0x7E,0x40,0x40,0x7C,0x02,0x02,0x02,0x42,0x3C,0x00,0x00, + + 8, // 0x36 '6' + 0x00,0x00,0x00,0x1C,0x20,0x40,0x7C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x37 '7' + 0x00,0x00,0x00,0x7E,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x00,0x00, + + 8, // 0x38 '8' + 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x3C,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x39 '9' + 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x3E,0x02,0x04,0x38,0x00,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x00,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x20,0x40, + + 9, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x00,0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, + + 12, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x27,0x40,0x49,0x20,0x49,0x20,0x49,0x20,0x49,0x20,0x27,0xC0,0x30,0x00,0x0F,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x42,0x42,0x7E,0x81,0x81,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x7C,0x42,0x42,0x42,0x7C,0x00,0x00, + + 9, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x7E,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x40,0x00,0x00, + + 9, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x47,0x00,0x41,0x00,0x41,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x4A 'J' + 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xE0,0x00,0x00, + + 8, // 0x4B 'K' + 0x00,0x00,0x00,0x42,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x42,0x00,0x00, + + 7, // 0x4C 'L' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7E,0x00,0x00, + + 10, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x52,0x80,0x52,0x80,0x52,0x80,0x4C,0x80,0x4C,0x80,0x40,0x80,0x40,0x80,0x00,0x00,0x00,0x00, + + 9, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x00,0x61,0x00,0x51,0x00,0x51,0x00,0x49,0x00,0x45,0x00,0x45,0x00,0x43,0x00,0x43,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x00,0x7C,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x00,0x00, + + 10, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x02,0x00,0x01,0x80, + + 8, // 0x52 'R' + 0x00,0x00,0x00,0x7C,0x42,0x42,0x42,0x7C,0x48,0x44,0x42,0x41,0x00,0x00, + + 8, // 0x53 'S' + 0x00,0x00,0x00,0x3C,0x42,0x40,0x40,0x3C,0x02,0x02,0x42,0x3C,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 9, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x00,0x81,0x81,0x42,0x42,0x42,0x24,0x24,0x18,0x18,0x00,0x00, + + 13, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x10,0x42,0x10,0x45,0x10,0x45,0x10,0x25,0x20,0x28,0xA0,0x28,0xA0,0x10,0x40,0x10,0x40,0x00,0x00,0x00,0x00, + + 8, // 0x58 'X' + 0x00,0x00,0x00,0x42,0x42,0x24,0x18,0x18,0x18,0x24,0x42,0x42,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0x00,0x82,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 8, // 0x5A 'Z' + 0x00,0x00,0x00,0x7E,0x02,0x04,0x08,0x10,0x10,0x20,0x40,0x7E,0x00,0x00, + + 5, // 0x5B '[' + 0x00,0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70, + + 5, // 0x5C '\' + 0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x08, + + 5, // 0x5D ']' + 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70, + + 10, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x12,0x00,0x21,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, + + 8, // 0x60 '`' + 0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x02,0x02,0x3E,0x42,0x42,0x3E,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x02,0x02,0x02,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x7E,0x40,0x42,0x3C,0x00,0x00, + + 4, // 0x66 'f' + 0x00,0x00,0x30,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x3C, + + 8, // 0x68 'h' + 0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 4, // 0x6A 'j' + 0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xC0, + + 7, // 0x6B 'k' + 0x00,0x00,0x40,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 11, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7B,0x80,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x00,0x00,0x00,0x00, + + 8, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00, + + 8, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x40,0x40, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x02, + + 5, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x40,0x40,0x38,0x04,0x04,0x78,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x00,0x00,0x40,0x40,0xF8,0x40,0x40,0x40,0x40,0x40,0x38,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, + + 11, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x10,0x20, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 8, // 0x7B '{' + 0x00,0x00,0x0C,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x10,0x0C, + + 5, // 0x7C '|' + 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + + 8, // 0x7D '}' + 0x00,0x00,0x30,0x08,0x08,0x08,0x08,0x06,0x08,0x08,0x08,0x08,0x08,0x30, + + 10, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x4C,0x80,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0xE0,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana14_bold[] = + { + 14, 3, 32, 128-32, + 0x00,0x00,0x0F,0x00,0x1E,0x00,0x2D,0x00,0x4A,0x00,0x67,0x00,0x84,0x00,0xA1,0x00,0xB0,0x00, + 0xBF,0x00,0xCE,0x00,0xEB,0x00,0x08,0x01,0x17,0x01,0x26,0x01,0x35,0x01,0x44,0x01,0x61,0x01, + 0x7E,0x01,0x9B,0x01,0xB8,0x01,0xD5,0x01,0xF2,0x01,0x0F,0x02,0x2C,0x02,0x49,0x02,0x66,0x02, + 0x75,0x02,0x84,0x02,0xA1,0x02,0xBE,0x02,0xDB,0x02,0xEA,0x02,0x07,0x03,0x24,0x03,0x41,0x03, + 0x5E,0x03,0x7B,0x03,0x8A,0x03,0x99,0x03,0xB6,0x03,0xD3,0x03,0xE2,0x03,0xF1,0x03,0x0E,0x04, + 0x1D,0x04,0x3A,0x04,0x57,0x04,0x74,0x04,0x91,0x04,0xAE,0x04,0xCB,0x04,0xE8,0x04,0xF7,0x04, + 0x14,0x05,0x31,0x05,0x4E,0x05,0x6B,0x05,0x88,0x05,0x97,0x05,0xA6,0x05,0xB5,0x05,0xC4,0x05, + 0xE1,0x05,0xFE,0x05,0x1B,0x06,0x2A,0x06,0x39,0x06,0x48,0x06,0x57,0x06,0x66,0x06,0x75,0x06, + 0x84,0x06,0x93,0x06,0xA2,0x06,0xB1,0x06,0xC0,0x06,0xCF,0x06,0xEC,0x06,0xFB,0x06,0x0A,0x07, + 0x19,0x07,0x28,0x07,0x37,0x07,0x46,0x07,0x55,0x07,0x64,0x07,0x73,0x07,0x90,0x07,0x9F,0x07, + 0xAE,0x07,0xBD,0x07,0xDA,0x07,0xE9,0x07,0x06,0x08,0x23,0x08, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x60,0x60,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x3F,0x80,0x3F,0x80,0x12,0x00,0x7F,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x69,0x00,0x68,0x00,0x7E,0x00,0x3F,0x00,0x0B,0x00,0x4B,0x00,0x3E,0x00,0x08,0x00,0x08,0x00, + + 15, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x6C,0x40,0x6C,0x80,0x6C,0xB8,0x6D,0x6C,0x3A,0x6C,0x02,0x6C,0x04,0x6C,0x04,0x38,0x00,0x00,0x00,0x00, + + 10, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x39,0x80,0x6D,0x00,0x66,0x00,0x63,0x00,0x3D,0x80,0x00,0x00,0x00,0x00, + + 4, // 0x27 ''' + 0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x00,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18, + + 7, // 0x29 ')' + 0x00,0x00,0x30,0x18,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x18,0x30, + + 9, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x08,0x00,0x2A,0x00,0x1C,0x00,0x1C,0x00,0x2A,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x40, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 8, // 0x2F '/' + 0x00,0x00,0x06,0x06,0x0C,0x0C,0x0C,0x18,0x18,0x30,0x30,0x30,0x60,0x60, + + 9, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x03,0x00,0x1E,0x00,0x03,0x00,0x03,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0E,0x00,0x16,0x00,0x16,0x00,0x26,0x00,0x46,0x00,0x7F,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x30,0x00,0x30,0x00,0x3E,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x30,0x00,0x60,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x03,0x00,0x06,0x00,0x3C,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x60,0x40, + + 10, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x00,0x00,0x38,0x4C,0x0C,0x18,0x30,0x30,0x00,0x30,0x30,0x00,0x00, + + 12, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x2F,0x40,0x5B,0x20,0x5B,0x20,0x5B,0x20,0x5B,0x20,0x2F,0xC0,0x30,0x00,0x0F,0x00,0x00,0x00, + + 9, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x7F,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x31,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x31,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x00,0x7E,0x60,0x60,0x60,0x7E,0x60,0x60,0x60,0x7E,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x00,0x7E,0x60,0x60,0x60,0x7E,0x60,0x60,0x60,0x60,0x00,0x00, + + 10, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x30,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x67,0x80,0x61,0x80,0x31,0x80,0x1F,0x80,0x00,0x00,0x00,0x00, + + 10, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x4A 'J' + 0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xF8,0x00,0x00, + + 9, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x66,0x00,0x6C,0x00,0x78,0x00,0x70,0x00,0x78,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4C 'L' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0x00,0x00, + + 11, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x71,0xC0,0x71,0xC0,0x5A,0xC0,0x5A,0xC0,0x4C,0xC0,0x4C,0xC0,0x40,0xC0,0x40,0xC0,0x00,0x00,0x00,0x00, + + 10, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x80,0x70,0x80,0x58,0x80,0x58,0x80,0x4C,0x80,0x46,0x80,0x46,0x80,0x43,0x80,0x41,0x80,0x00,0x00,0x00,0x00, + + 11, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x06,0x00,0x03,0xC0, + + 9, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00, + + 9, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x61,0x00,0x60,0x00,0x70,0x00,0x3E,0x00,0x07,0x00,0x03,0x00,0x43,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x54 'T' + 0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, + + 10, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x63,0x18,0x33,0x30,0x37,0xB0,0x34,0xB0,0x1C,0xE0,0x18,0x60,0x18,0x60,0x00,0x00,0x00,0x00, + + 9, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5A 'Z' + 0x00,0x00,0x00,0x7E,0x0C,0x0C,0x18,0x18,0x30,0x30,0x60,0x7E,0x00,0x00, + + 6, // 0x5B '[' + 0x00,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78, + + 8, // 0x5C '\' + 0x00,0x00,0x60,0x60,0x30,0x30,0x30,0x18,0x18,0x0C,0x0C,0x0C,0x06,0x06, + + 6, // 0x5D ']' + 0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78, + + 10, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80, + + 9, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x7C,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x62,0x60,0x60,0x60,0x62,0x3C,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x06,0x06,0x06,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x66,0x7E,0x60,0x62,0x3C,0x00,0x00, + + 5, // 0x66 'f' + 0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C, + + 8, // 0x68 'h' + 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00, + + 4, // 0x69 'i' + 0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x00,0x30,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xE0, + + 8, // 0x6B 'k' + 0x00,0x00,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x63,0x00,0x00, + + 4, // 0x6C 'l' + 0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 12, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0xC0,0x77,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x00,0x00,0x00,0x00, + + 8, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00, + + 8, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x06, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x6C,0x7C,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x60,0x60,0x38,0x0C,0x0C,0x78,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x38,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x3C,0x18,0x00,0x00, + + 12, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,0x66,0x60,0x66,0x60,0x69,0x60,0x39,0xC0,0x30,0xC0,0x30,0xC0,0x00,0x00,0x00,0x00, + + 8, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x3C,0x18,0x18,0x30, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x0C,0x18,0x38,0x30,0x60,0x7C,0x00,0x00, + + 9, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x0E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x0E,0x00, + + 6, // 0x7C '|' + 0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, + + 9, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x38,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x38,0x00, + + 10, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x48,0x80,0x44,0x80,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0xE0,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana16[] = + { + 16, 4, 32, 128-32, + 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x54,0x00,0x65,0x00,0x86,0x00,0xA7,0x00,0xB8,0x00, + 0xC9,0x00,0xDA,0x00,0xFB,0x00,0x1C,0x01,0x2D,0x01,0x3E,0x01,0x4F,0x01,0x60,0x01,0x71,0x01, + 0x82,0x01,0x93,0x01,0xA4,0x01,0xB5,0x01,0xC6,0x01,0xD7,0x01,0xE8,0x01,0xF9,0x01,0x0A,0x02, + 0x1B,0x02,0x2C,0x02,0x4D,0x02,0x6E,0x02,0x8F,0x02,0xA0,0x02,0xC1,0x02,0xE2,0x02,0xF3,0x02, + 0x14,0x03,0x35,0x03,0x46,0x03,0x57,0x03,0x78,0x03,0x99,0x03,0xAA,0x03,0xBB,0x03,0xCC,0x03, + 0xDD,0x03,0xFE,0x03,0x1F,0x04,0x40,0x04,0x51,0x04,0x72,0x04,0x93,0x04,0xB4,0x04,0xD5,0x04, + 0xF6,0x04,0x17,0x05,0x38,0x05,0x59,0x05,0x7A,0x05,0x9B,0x05,0xAC,0x05,0xBD,0x05,0xCE,0x05, + 0xEF,0x05,0x00,0x06,0x11,0x06,0x22,0x06,0x33,0x06,0x44,0x06,0x55,0x06,0x66,0x06,0x77,0x06, + 0x88,0x06,0x99,0x06,0xAA,0x06,0xBB,0x06,0xCC,0x06,0xDD,0x06,0xFE,0x06,0x0F,0x07,0x20,0x07, + 0x31,0x07,0x42,0x07,0x53,0x07,0x64,0x07,0x75,0x07,0x86,0x07,0x97,0x07,0xB8,0x07,0xC9,0x07, + 0xDA,0x07,0xEB,0x07,0xFC,0x07,0x0D,0x08,0x1E,0x08,0x3F,0x08, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x00,0x00,0x00, + + 5, // 0x22 '"' + 0x00,0x00,0x00,0x50,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x3F,0x80,0x12,0x00,0x12,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x24 '$' + 0x00,0x00,0x00,0x10,0x10,0x3E,0x50,0x50,0x30,0x1C,0x12,0x12,0x7C,0x10,0x10,0x00, + + 13, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x44,0x80,0x45,0x00,0x45,0x00,0x3A,0xE0,0x05,0x10,0x05,0x10,0x09,0x10,0x10,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x44,0x00,0x44,0x00,0x44,0x00,0x38,0x80,0x45,0x00,0x42,0x00,0x46,0x00,0x39,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x00,0x00,0x00,0x08,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x08, + + 6, // 0x29 ')' + 0x00,0x00,0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40, + + 9, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x2F '/' + 0x00,0x00,0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, + + 8, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00,0x00, + + 8, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x20,0x40,0x7E,0x00,0x00,0x00, + + 8, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x1C,0x02,0x02,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x44,0x7F,0x04,0x04,0x04,0x00,0x00,0x00, + + 8, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x3E,0x20,0x20,0x20,0x3C,0x02,0x02,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x1C,0x20,0x40,0x7C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x7E,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x00,0x00,0x00, + + 8, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x3C,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x3E,0x02,0x04,0x38,0x00,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, + + 9, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, + + 13, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x10,0x40,0x27,0xA0,0x48,0x90,0x48,0x90,0x48,0x90,0x48,0x90,0x48,0x90,0x27,0xE0,0x10,0x00,0x0F,0x80,0x00,0x00, + + 9, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x14,0x00,0x22,0x00,0x22,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x7C,0x42,0x42,0x42,0x7C,0x00,0x00,0x00, + + 9, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x7E,0x00,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 9, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x47,0x00,0x41,0x00,0x21,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x00, + + 8, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x42,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x42,0x00,0x00,0x00, + + 7, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7E,0x00,0x00,0x00, + + 11, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x51,0x40,0x51,0x40,0x4A,0x40,0x4A,0x40,0x44,0x40,0x44,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x00,0x61,0x00,0x51,0x00,0x51,0x00,0x49,0x00,0x45,0x00,0x45,0x00,0x43,0x00,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x7C,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x00,0x00,0x00, + + 10, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x02,0x00,0x01,0x80,0x00,0x00, + + 9, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x44,0x00,0x78,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x40,0x00,0x40,0x00,0x3E,0x00,0x01,0x00,0x01,0x00,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x54 'T' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x10,0x42,0x10,0x45,0x10,0x45,0x10,0x25,0x20,0x28,0xA0,0x28,0xA0,0x10,0x40,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5B '[' + 0x00,0x00,0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + + 6, // 0x5C '\' + 0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, + + 6, // 0x5D ']' + 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, + + 11, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, + + 8, // 0x60 '`' + 0x00,0x00,0x00,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x02,0x02,0x3E,0x42,0x42,0x3E,0x00,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x40,0x40,0x40,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x00,0x02,0x02,0x02,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x7E,0x40,0x42,0x3C,0x00,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x00,0x00,0x1C,0x20,0x20,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x3C, + + 8, // 0x68 'h' + 0x00,0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 4, // 0x6A 'j' + 0x00,0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xC0, + + 7, // 0x6B 'k' + 0x00,0x00,0x00,0x40,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 11, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0x80,0x66,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00, + + 8, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x02, + + 5, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x40,0x40,0x38,0x04,0x04,0x78,0x00,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x00,0x00,0x00,0x20,0x20,0x78,0x20,0x20,0x20,0x20,0x20,0x18,0x00,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x00,0x00,0x00, + + 11, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x10,0x10,0x20, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, + + 8, // 0x7B '{' + 0x00,0x00,0x00,0x0C,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x10,0x0C,0x00, + + 7, // 0x7C '|' + 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, + + 8, // 0x7D '}' + 0x00,0x00,0x00,0x30,0x08,0x08,0x08,0x08,0x06,0x08,0x08,0x08,0x08,0x08,0x30,0x00, + + 11, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x4C,0x80,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF0,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana16_bold[] = + { + 16, 4, 32, 128-32, + 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x54,0x00,0x75,0x00,0xA6,0x00,0xC7,0x00,0xD8,0x00, + 0xE9,0x00,0xFA,0x00,0x1B,0x01,0x3C,0x01,0x4D,0x01,0x5E,0x01,0x6F,0x01,0x90,0x01,0xB1,0x01, + 0xD2,0x01,0xF3,0x01,0x14,0x02,0x35,0x02,0x56,0x02,0x77,0x02,0x98,0x02,0xB9,0x02,0xDA,0x02, + 0xEB,0x02,0xFC,0x02,0x1D,0x03,0x3E,0x03,0x5F,0x03,0x70,0x03,0x91,0x03,0xB2,0x03,0xD3,0x03, + 0xF4,0x03,0x15,0x04,0x36,0x04,0x57,0x04,0x78,0x04,0x99,0x04,0xAA,0x04,0xBB,0x04,0xDC,0x04, + 0xED,0x04,0x0E,0x05,0x2F,0x05,0x50,0x05,0x71,0x05,0x92,0x05,0xB3,0x05,0xD4,0x05,0xE5,0x05, + 0x06,0x06,0x27,0x06,0x48,0x06,0x69,0x06,0x8A,0x06,0xAB,0x06,0xBC,0x06,0xDD,0x06,0xEE,0x06, + 0x0F,0x07,0x30,0x07,0x51,0x07,0x72,0x07,0x93,0x07,0xA4,0x07,0xC5,0x07,0xE6,0x07,0xF7,0x07, + 0x18,0x08,0x39,0x08,0x4A,0x08,0x5B,0x08,0x6C,0x08,0x7D,0x08,0x9E,0x08,0xBF,0x08,0xE0,0x08, + 0x01,0x09,0x22,0x09,0x33,0x09,0x44,0x09,0x55,0x09,0x76,0x09,0x97,0x09,0xB8,0x09,0xD9,0x09, + 0xFA,0x09,0x0B,0x0A,0x2C,0x0A,0x3D,0x0A,0x5E,0x0A,0x7F,0x0A, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x00,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x3F,0x80,0x3F,0x80,0x12,0x00,0x7F,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x69,0x00,0x68,0x00,0x78,0x00,0x3E,0x00,0x0F,0x00,0x0B,0x00,0x4B,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x00,0x00, + + 17, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x20,0x00,0x66,0x20,0x00,0x66,0x40,0x00,0x66,0x5E,0x00,0x66,0xB3,0x00,0x3D,0x33,0x00,0x01,0x33,0x00,0x02,0x33,0x00,0x02,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x66,0x00,0x66,0x00,0x66,0xC0,0x3C,0xC0,0x66,0x80,0x63,0x00,0x63,0x80,0x3C,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x27 ''' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x00,0x00,0x0C,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18,0x0C, + + 7, // 0x29 ')' + 0x00,0x00,0x00,0x60,0x30,0x18,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x18,0x30,0x60, + + 9, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x60,0x60,0xC0,0xC0, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 9, // 0x2F '/' + 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x00,0x00, + + 9, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x03,0x00,0x0E,0x00,0x03,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0E,0x00,0x16,0x00,0x26,0x00,0x46,0x00,0x7F,0x80,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x30,0x00,0x30,0x00,0x3E,0x00,0x03,0x00,0x03,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x30,0x00,0x60,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x03,0x00,0x06,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x38,0x30,0x30,0x60,0x60, + + 11, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x40,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x3C,0x66,0x06,0x0C,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00, + + 13, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0x60,0x27,0xA0,0x4D,0x90,0x4D,0x90,0x4D,0x90,0x4D,0x90,0x27,0xE0,0x30,0x00,0x0F,0x80,0x00,0x00,0x00,0x00, + + 10, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x1E,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x7F,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x61,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x61,0x80,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x61,0x80,0x60,0x00,0x60,0x00,0x63,0x80,0x61,0x80,0x31,0x80,0x1F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x7F,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, + + 7, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xF8,0x00,0x00,0x00, + + 9, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x66,0x00,0x6C,0x00,0x78,0x00,0x78,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0x00,0x00,0x00, + + 12, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xE0,0x70,0xE0,0x59,0x60,0x59,0x60,0x4E,0x60,0x4E,0x60,0x44,0x60,0x44,0x60,0x40,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x80,0x70,0x80,0x58,0x80,0x58,0x80,0x4C,0x80,0x46,0x80,0x46,0x80,0x43,0x80,0x43,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x03,0x00,0x01,0xC0,0x00,0x00, + + 9, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x70,0x00,0x3E,0x00,0x07,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x54 'T' + 0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00, + + 10, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x63,0x18,0x33,0x30,0x37,0xB0,0x34,0xB0,0x1C,0xE0,0x18,0x60,0x18,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5B '[' + 0x00,0x00,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78,0x00, + + 9, // 0x5C '\' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x00,0x00, + + 6, // 0x5D ']' + 0x00,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x00, + + 10, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x00,0x00, + + 9, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x03,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x62 'b' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00, + + 9, // 0x64 'd' + 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x7F,0x00,0x60,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x66 'f' + 0x00,0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 9, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x03,0x00,0x03,0x00,0x3E,0x00, + + 9, // 0x68 'h' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x69 'i' + 0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x00,0x00,0x30,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xE0, + + 8, // 0x6B 'k' + 0x00,0x00,0x00,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x63,0x00,0x00,0x00, + + 4, // 0x6C 'l' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 14, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x70,0x73,0x98,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00, + + 9, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x03,0x00,0x03,0x00,0x03,0x00, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x7C,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x60,0x70,0x3C,0x0E,0x06,0x7C,0x00,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x38,0x00,0x00,0x00, + + 9, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,0x66,0x60,0x66,0x60,0x69,0x60,0x39,0xC0,0x30,0xC0,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00, + + 8, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00,0x00, + + 9, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x00,0x00,0x00, + + 8, // 0x7C '|' + 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00, + + 9, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x07,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x70,0x00,0x00,0x00, + + 11, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x44,0x40,0x44,0x40,0x43,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF0,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana17[] = + { + 17, 4, 32, 128-32, + 0x00,0x00,0x12,0x00,0x24,0x00,0x36,0x00,0x59,0x00,0x7C,0x00,0x9F,0x00,0xC2,0x00,0xD4,0x00, + 0xE6,0x00,0xF8,0x00,0x1B,0x01,0x3E,0x01,0x50,0x01,0x62,0x01,0x74,0x01,0x86,0x01,0xA9,0x01, + 0xCC,0x01,0xEF,0x01,0x12,0x02,0x35,0x02,0x58,0x02,0x7B,0x02,0x9E,0x02,0xC1,0x02,0xE4,0x02, + 0xF6,0x02,0x08,0x03,0x2B,0x03,0x4E,0x03,0x71,0x03,0x83,0x03,0xA6,0x03,0xC9,0x03,0xEC,0x03, + 0x0F,0x04,0x32,0x04,0x55,0x04,0x67,0x04,0x8A,0x04,0xAD,0x04,0xBF,0x04,0xD1,0x04,0xF4,0x04, + 0x06,0x05,0x29,0x05,0x4C,0x05,0x6F,0x05,0x81,0x05,0xA4,0x05,0xC7,0x05,0xEA,0x05,0x0D,0x06, + 0x30,0x06,0x53,0x06,0x76,0x06,0x99,0x06,0xBC,0x06,0xDF,0x06,0xF1,0x06,0x03,0x07,0x15,0x07, + 0x38,0x07,0x5B,0x07,0x7E,0x07,0x90,0x07,0xB3,0x07,0xC5,0x07,0xE8,0x07,0xFA,0x07,0x0C,0x08, + 0x2F,0x08,0x52,0x08,0x64,0x08,0x76,0x08,0x88,0x08,0x9A,0x08,0xBD,0x08,0xE0,0x08,0x03,0x09, + 0x26,0x09,0x49,0x09,0x5B,0x09,0x6D,0x09,0x7F,0x09,0xA2,0x09,0xB4,0x09,0xD7,0x09,0xFA,0x09, + 0x0C,0x0A,0x1E,0x0A,0x41,0x0A,0x53,0x0A,0x76,0x0A,0x99,0x0A, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x22 '"' + 0x00,0x00,0x00,0x48,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x04,0x80,0x09,0x00,0x3F,0xC0,0x09,0x00,0x12,0x00,0x7F,0x80,0x12,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x49,0x00,0x48,0x00,0x48,0x00,0x3E,0x00,0x09,0x00,0x09,0x00,0x49,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x00,0x00, + + 15, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x20,0x44,0x40,0x44,0x80,0x44,0x80,0x45,0x38,0x39,0x44,0x02,0x44,0x04,0x44,0x04,0x44,0x08,0x38,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x44,0x00,0x38,0x80,0x44,0x80,0x42,0x80,0x41,0x00,0x22,0x80,0x1C,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x27 ''' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x00,0x00,0x00,0x08,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x08, + + 6, // 0x29 ')' + 0x00,0x00,0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40, + + 9, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x2F '/' + 0x00,0x00,0x00,0x04,0x08,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x80,0x80,0x00, + + 9, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x38,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x0C,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x01,0x00,0x02,0x00,0x1C,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x06,0x00,0x0A,0x00,0x12,0x00,0x22,0x00,0x42,0x00,0x7F,0x80,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7C,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x30,0x00,0x20,0x00,0x40,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x21,0x00,0x1F,0x00,0x01,0x00,0x02,0x00,0x06,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, + + 11, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x06,0x00,0x18,0x00,0x60,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xC0,0x00,0x00,0x00,0x00,0x3F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x0C,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, + + 14, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x18,0x20,0x20,0x10,0x27,0xC8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x27,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, + + 10, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x7F,0x80,0x40,0x80,0x80,0x40,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7E,0x00,0x41,0x00,0x40,0x80,0x40,0x80,0x41,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0x80,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x30,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x80,0x40,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x41,0x80,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 11, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x00,0x40,0x00,0x43,0xC0,0x40,0x40,0x20,0x40,0x30,0x40,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7F,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x00, + + 10, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x42,0x00,0x44,0x00,0x48,0x00,0x50,0x00,0x68,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x00,0x00,0x00, + + 11, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x51,0x40,0x51,0x40,0x4A,0x40,0x4A,0x40,0x44,0x40,0x44,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x80,0x60,0x80,0x50,0x80,0x48,0x80,0x48,0x80,0x44,0x80,0x44,0x80,0x42,0x80,0x41,0x80,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x31,0x80,0x20,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x80,0x31,0x80,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x7C,0x42,0x41,0x41,0x42,0x7C,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 11, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x31,0x80,0x20,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x80,0x31,0x80,0x0E,0x00,0x02,0x00,0x02,0x00,0x01,0xC0, + + 10, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x44,0x00,0x78,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x40,0x00,0x40,0x00,0x38,0x00,0x07,0x00,0x00,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x54 'T' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x80,0x40,0x40,0x80,0x40,0x80,0x21,0x00,0x21,0x00,0x21,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 15, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x04,0x41,0x04,0x22,0x88,0x22,0x88,0x22,0x88,0x14,0x50,0x14,0x50,0x14,0x50,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x21,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5B '[' + 0x00,0x00,0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3C, + + 6, // 0x5C '\' + 0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x08,0x04,0x00, + + 6, // 0x5D ']' + 0x00,0x00,0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78, + + 11, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x00,0x00, + + 9, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x02,0x3E,0x42,0x42,0x46,0x3A,0x00,0x00,0x00, + + 9, // 0x62 'b' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x40,0x22,0x1C,0x00,0x00,0x00, + + 9, // 0x64 'd' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x42,0x7E,0x40,0x40,0x22,0x1C,0x00,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x00,0x00,0x1C,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, + + 9, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x22,0x00,0x1C,0x00, + + 9, // 0x68 'h' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x00,0x00,0x00,0x10,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xE0, + + 8, // 0x6B 'k' + 0x00,0x00,0x00,0x40,0x40,0x40,0x42,0x44,0x48,0x50,0x70,0x48,0x44,0x42,0x00,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 13, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0xE0,0x63,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x40,0x00,0x40,0x00,0x40,0x00, + + 9, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x01,0x00,0x01,0x00, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x40,0x30,0x0C,0x02,0x42,0x3C,0x00,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x00,0x00,0x00,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x1C,0x00,0x00,0x00, + + 9, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x43,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x18,0x00,0x00,0x00, + + 11, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x18,0x10,0x10,0x20, + + 8, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x02,0x04,0x08,0x10,0x20,0x40,0x7E,0x00,0x00,0x00, + + 9, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x60,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x07,0x00, + + 6, // 0x7C '|' + 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + + 9, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x04,0x00,0x03,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x70,0x00, + + 11, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x44,0x40,0x44,0x40,0x43,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana17_bold[] = + { + 17, 4, 32, 128-32, + 0x00,0x00,0x12,0x00,0x24,0x00,0x36,0x00,0x59,0x00,0x7C,0x00,0xB0,0x00,0xD3,0x00,0xE5,0x00, + 0xF7,0x00,0x09,0x01,0x2C,0x01,0x4F,0x01,0x61,0x01,0x73,0x01,0x85,0x01,0xA8,0x01,0xCB,0x01, + 0xEE,0x01,0x11,0x02,0x34,0x02,0x57,0x02,0x7A,0x02,0x9D,0x02,0xC0,0x02,0xE3,0x02,0x06,0x03, + 0x18,0x03,0x2A,0x03,0x4D,0x03,0x70,0x03,0x93,0x03,0xB6,0x03,0xD9,0x03,0xFC,0x03,0x1F,0x04, + 0x42,0x04,0x65,0x04,0x88,0x04,0xAB,0x04,0xCE,0x04,0xF1,0x04,0x03,0x05,0x15,0x05,0x38,0x05, + 0x5B,0x05,0x7E,0x05,0xA1,0x05,0xC4,0x05,0xE7,0x05,0x0A,0x06,0x2D,0x06,0x50,0x06,0x73,0x06, + 0x96,0x06,0xB9,0x06,0xDC,0x06,0xFF,0x06,0x22,0x07,0x45,0x07,0x57,0x07,0x7A,0x07,0x8C,0x07, + 0xAF,0x07,0xD2,0x07,0xF5,0x07,0x18,0x08,0x3B,0x08,0x4D,0x08,0x70,0x08,0x93,0x08,0xA5,0x08, + 0xC8,0x08,0xEB,0x08,0xFD,0x08,0x0F,0x09,0x32,0x09,0x44,0x09,0x67,0x09,0x8A,0x09,0xAD,0x09, + 0xD0,0x09,0xF3,0x09,0x05,0x0A,0x17,0x0A,0x29,0x0A,0x4C,0x0A,0x6F,0x0A,0x92,0x0A,0xB5,0x0A, + 0xD8,0x0A,0xEA,0x0A,0x0D,0x0B,0x1F,0x0B,0x42,0x0B,0x65,0x0B, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, + + 8, // 0x22 '"' + 0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x40,0x04,0x40,0x3F,0xE0,0x3F,0xE0,0x08,0x80,0x11,0x00,0x7F,0xC0,0x7F,0xC0,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1F,0x00,0x34,0x80,0x64,0x00,0x74,0x00,0x3C,0x00,0x0F,0x00,0x0B,0x80,0x09,0x80,0x4B,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x00,0x00, + + 18, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x08,0x00,0x66,0x10,0x00,0x66,0x20,0x00,0x66,0x2F,0x00,0x66,0x59,0x80,0x66,0x99,0x80,0x3D,0x19,0x80,0x01,0x19,0x80,0x02,0x19,0x80,0x04,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x36,0x00,0x1C,0x60,0x36,0x60,0x63,0x60,0x61,0xC0,0x31,0xC0,0x1F,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x27 ''' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x28 '(' + 0x00,0x00,0x00,0x0C,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18,0x0C, + + 8, // 0x29 ')' + 0x00,0x00,0x00,0x30,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x30, + + 10, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x60,0x60,0xC0,0xC0,0x00, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, + + 10, // 0x2F '/' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x00,0x00, + + 10, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x61,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x61,0x80,0x01,0x80,0x0F,0x00,0x03,0x00,0x01,0x80,0x61,0x80,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x07,0x00,0x0B,0x00,0x13,0x00,0x23,0x00,0x43,0x00,0x7F,0xC0,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x30,0x00,0x30,0x00,0x3E,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x61,0x80,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x38,0x00,0x30,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x03,0x00,0x07,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x38,0x30,0x30,0x60,0x60,0x00, + + 12, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x40,0x01,0x80,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x18,0x20,0x20,0x10,0x27,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x27,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, + + 11, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1B,0x00,0x1B,0x00,0x31,0x80,0x3F,0x80,0x31,0x80,0x60,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0xC0,0x30,0xC0,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x30,0xC0,0x30,0xC0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x61,0x80,0x61,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x61,0x80,0x61,0x80,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0xC0,0x30,0xC0,0x60,0x00,0x60,0x00,0x63,0xC0,0x60,0xC0,0x30,0xC0,0x30,0xC0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x7F,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00, + + 8, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x3E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0xF8,0x00,0x00,0x00, + + 11, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x61,0x80,0x63,0x00,0x66,0x00,0x6C,0x00,0x7C,0x00,0x76,0x00,0x63,0x00,0x61,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x70,0x70,0x70,0x70,0xF0,0x58,0xB0,0x59,0xB0,0x4D,0x30,0x4F,0x30,0x46,0x30,0x46,0x30,0x40,0x30,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x40,0x70,0x40,0x58,0x40,0x4C,0x40,0x4C,0x40,0x46,0x40,0x43,0x40,0x43,0x40,0x41,0xC0,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x30,0xC0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0xC0,0x30,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x30,0xC0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0xC0,0x30,0xC0,0x0F,0x80,0x03,0x00,0x03,0x00,0x01,0xE0, + + 11, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x63,0x00,0x61,0x80,0x60,0xC0,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x61,0x80,0x60,0x00,0x3E,0x00,0x1F,0x00,0x01,0x80,0x61,0x80,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x54 'T' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x31,0x80,0x31,0x80,0x1B,0x00,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 16, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x86,0x61,0x86,0x63,0xC6,0x32,0x4C,0x36,0x6C,0x36,0x6C,0x34,0x2C,0x1C,0x38,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x31,0x80,0x31,0x80,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x1B,0x00,0x31,0x80,0x31,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5B '[' + 0x00,0x00,0x00,0x3E,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3E, + + 10, // 0x5C '\' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x00,0x00, + + 8, // 0x5D ']' + 0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x7C, + + 12, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0E,0x00,0x1B,0x00,0x31,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00, + + 10, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x03,0x00,0x03,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x62 'b' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x33,0x60,0x60,0x60,0x60,0x33,0x1E,0x00,0x00,0x00, + + 10, // 0x64 'd' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x63,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x00,0x00,0x1C,0x30,0x30,0x7C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, + + 10, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x03,0x00,0x3E,0x00, + + 10, // 0x68 'h' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x69 'i' + 0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 6, // 0x6A 'j' + 0x00,0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF0, + + 9, // 0x6B 'k' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x63,0x00,0x66,0x00,0x6C,0x00,0x78,0x00,0x7C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x6C 'l' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 14, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x70,0x73,0x98,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00, + + 10, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x01,0x80,0x01,0x80, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x7E,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x62,0x60,0x7C,0x3E,0x06,0x46,0x3C,0x00,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x00,0x00,0x00,0x60,0x60,0xFC,0x60,0x60,0x60,0x60,0x60,0x60,0x3C,0x00,0x00,0x00, + + 10, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x80,0x3D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x33,0x30,0x37,0xB0,0x34,0xB0,0x1C,0xE0,0x1C,0xE0,0x0C,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00, + + 8, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x06,0x0C,0x18,0x18,0x30,0x60,0x7E,0x00,0x00,0x00, + + 10, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x80, + + 8, // 0x7C '|' + 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + + 10, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x03,0x80,0x06,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x78,0x00, + + 12, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x20,0x24,0x20,0x46,0x20,0x42,0x40,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana18[] = + { + 18, 4, 32, 128-32, + 0x00,0x00,0x13,0x00,0x26,0x00,0x39,0x00,0x5E,0x00,0x83,0x00,0xA8,0x00,0xCD,0x00,0xE0,0x00, + 0xF3,0x00,0x06,0x01,0x2B,0x01,0x50,0x01,0x63,0x01,0x76,0x01,0x89,0x01,0x9C,0x01,0xC1,0x01, + 0xE6,0x01,0x0B,0x02,0x30,0x02,0x55,0x02,0x7A,0x02,0x9F,0x02,0xC4,0x02,0xE9,0x02,0x0E,0x03, + 0x21,0x03,0x34,0x03,0x59,0x03,0x7E,0x03,0xA3,0x03,0xB6,0x03,0xDB,0x03,0x00,0x04,0x25,0x04, + 0x4A,0x04,0x6F,0x04,0x94,0x04,0xB9,0x04,0xDE,0x04,0x03,0x05,0x16,0x05,0x29,0x05,0x4E,0x05, + 0x61,0x05,0x86,0x05,0xAB,0x05,0xD0,0x05,0xF5,0x05,0x1A,0x06,0x3F,0x06,0x64,0x06,0x89,0x06, + 0xAE,0x06,0xD3,0x06,0xF8,0x06,0x1D,0x07,0x42,0x07,0x67,0x07,0x7A,0x07,0x8D,0x07,0xA0,0x07, + 0xC5,0x07,0xEA,0x07,0x0F,0x08,0x34,0x08,0x59,0x08,0x6C,0x08,0x91,0x08,0xB6,0x08,0xC9,0x08, + 0xEE,0x08,0x13,0x09,0x26,0x09,0x39,0x09,0x5E,0x09,0x71,0x09,0x96,0x09,0xBB,0x09,0xE0,0x09, + 0x05,0x0A,0x2A,0x0A,0x3D,0x0A,0x50,0x0A,0x63,0x0A,0x88,0x0A,0xAD,0x0A,0xD2,0x0A,0xF7,0x0A, + 0x1C,0x0B,0x41,0x0B,0x66,0x0B,0x79,0x0B,0x9E,0x0B,0xC3,0x0B, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x00,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x00,0x48,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x04,0x80,0x09,0x00,0x3F,0xC0,0x09,0x00,0x11,0x00,0x12,0x00,0x7F,0x80,0x12,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x49,0x00,0x48,0x00,0x48,0x00,0x38,0x00,0x0E,0x00,0x09,0x00,0x09,0x00,0x49,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x08,0x00, + + 16, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x20,0x44,0x40,0x44,0x40,0x44,0x80,0x44,0x80,0x38,0x9C,0x01,0x22,0x01,0x22,0x02,0x22,0x02,0x22,0x04,0x1C,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x1E,0x40,0x24,0x40,0x42,0x40,0x41,0x40,0x40,0x80,0x21,0x40,0x1E,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x27 ''' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x00,0x00,0x08,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x08, + + 7, // 0x29 ')' + 0x00,0x00,0x00,0x20,0x10,0x08,0x08,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20, + + 10, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x3F,0xE0,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x40, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, + + 7, // 0x2F '/' + 0x00,0x00,0x00,0x02,0x04,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x00, + + 10, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1C,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x40,0x80,0x00,0x80,0x01,0x00,0x0E,0x00,0x01,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x05,0x00,0x09,0x00,0x11,0x00,0x21,0x00,0x41,0x00,0x7F,0xC0,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x20,0x00,0x20,0x00,0x20,0x00,0x3E,0x00,0x01,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x5E,0x00,0x61,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x20,0x80,0x1F,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x20,0x20, + + 12, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x04,0x08,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, + + 15, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x18,0x60,0x20,0x10,0x23,0xD0,0x44,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x44,0x48,0x23,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, + + 10, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x21,0x00,0x40,0x80,0x7F,0x80,0x40,0x80,0x80,0x40,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7E,0x00,0x41,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x41,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x40,0x30,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x80,0x40,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x41,0x80,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0x60,0x20,0x20,0x40,0x00,0x40,0x00,0x41,0xE0,0x40,0x20,0x40,0x20,0x20,0x20,0x30,0x20,0x0F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 7, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x3C,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0xF0,0x00,0x00,0x00, + + 10, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x41,0x00,0x42,0x00,0x44,0x00,0x48,0x00,0x50,0x00,0x68,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x00,0x00,0x00, + + 13, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x30,0x50,0x50,0x50,0x50,0x48,0x90,0x48,0x90,0x45,0x10,0x45,0x10,0x42,0x10,0x42,0x10,0x40,0x10,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x60,0x40,0x50,0x40,0x48,0x40,0x48,0x40,0x44,0x40,0x42,0x40,0x42,0x40,0x41,0x40,0x40,0xC0,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x20,0x40,0x30,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x41,0x00,0x7E,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x20,0x40,0x30,0xC0,0x0F,0x00,0x01,0x00,0x01,0x00,0x00,0xE0, + + 10, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x40,0x00,0x40,0x00,0x20,0x00,0x1E,0x00,0x01,0x00,0x00,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x54 'T' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x80,0x40,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x21,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 15, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x04,0x41,0x04,0x22,0x88,0x22,0x88,0x22,0x88,0x12,0x90,0x14,0x50,0x14,0x50,0x14,0x50,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x21,0x00,0x21,0x00,0x12,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x12,0x00,0x21,0x00,0x21,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5B '[' + 0x00,0x00,0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3C, + + 7, // 0x5C '\' + 0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x04,0x02,0x00, + + 7, // 0x5D ']' + 0x00,0x00,0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78, + + 12, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x00,0x10,0x80,0x20,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00, + + 10, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x01,0x00,0x3F,0x00,0x41,0x00,0x41,0x00,0x43,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x62 'b' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x21,0x40,0x40,0x40,0x40,0x21,0x1E,0x00,0x00,0x00, + + 9, // 0x64 'd' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x00,0x00,0x1C,0x20,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, + + 9, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x22,0x00,0x1C,0x00, + + 9, // 0x68 'h' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xE0, + + 9, // 0x6B 'k' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x42,0x00,0x44,0x00,0x48,0x00,0x50,0x00,0x68,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 15, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2E,0x70,0x31,0x88,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x40,0x00,0x40,0x00,0x40,0x00, + + 9, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x01,0x00,0x01,0x00, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x40,0x30,0x0C,0x02,0x42,0x3C,0x00,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x1C,0x00,0x00,0x00, + + 9, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x43,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x10,0x42,0x10,0x25,0x20,0x25,0x20,0x28,0xA0,0x28,0xA0,0x10,0x40,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x10,0x00, + + 9, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x60,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x07,0x00, + + 7, // 0x7C '|' + 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + + 10, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x38,0x00, + + 12, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x20,0x24,0x20,0x42,0x40,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 15, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana18_bold[] = + { + 18, 4, 32, 128-32, + 0x00,0x00,0x13,0x00,0x26,0x00,0x4B,0x00,0x70,0x00,0x95,0x00,0xCC,0x00,0xF1,0x00,0x04,0x01, + 0x17,0x01,0x2A,0x01,0x4F,0x01,0x74,0x01,0x87,0x01,0x9A,0x01,0xAD,0x01,0xD2,0x01,0xF7,0x01, + 0x1C,0x02,0x41,0x02,0x66,0x02,0x8B,0x02,0xB0,0x02,0xD5,0x02,0xFA,0x02,0x1F,0x03,0x44,0x03, + 0x57,0x03,0x6A,0x03,0x8F,0x03,0xB4,0x03,0xD9,0x03,0xFE,0x03,0x23,0x04,0x48,0x04,0x6D,0x04, + 0x92,0x04,0xB7,0x04,0xDC,0x04,0x01,0x05,0x26,0x05,0x4B,0x05,0x5E,0x05,0x71,0x05,0x96,0x05, + 0xBB,0x05,0xE0,0x05,0x05,0x06,0x2A,0x06,0x4F,0x06,0x74,0x06,0x99,0x06,0xBE,0x06,0xE3,0x06, + 0x08,0x07,0x2D,0x07,0x52,0x07,0x77,0x07,0x9C,0x07,0xC1,0x07,0xD4,0x07,0xF9,0x07,0x0C,0x08, + 0x31,0x08,0x56,0x08,0x7B,0x08,0xA0,0x08,0xC5,0x08,0xD8,0x08,0xFD,0x08,0x22,0x09,0x35,0x09, + 0x5A,0x09,0x7F,0x09,0x92,0x09,0xA5,0x09,0xCA,0x09,0xDD,0x09,0x02,0x0A,0x27,0x0A,0x4C,0x0A, + 0x71,0x0A,0x96,0x0A,0xA9,0x0A,0xCE,0x0A,0xE1,0x0A,0x06,0x0B,0x2B,0x0B,0x50,0x0B,0x75,0x0B, + 0x9A,0x0B,0xBF,0x0B,0xE4,0x0B,0xF7,0x0B,0x1C,0x0C,0x41,0x0C, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, + + 9, // 0x22 '"' + 0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x20,0x04,0x20,0x08,0x40,0x3F,0xF0,0x3F,0xF0,0x08,0x40,0x10,0x80,0x7F,0xE0,0x7F,0xE0,0x21,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1F,0x80,0x34,0xC0,0x64,0xC0,0x64,0x00,0x3C,0x00,0x07,0x80,0x04,0xC0,0x64,0xC0,0x65,0x80,0x3F,0x00,0x04,0x00,0x04,0x00,0x00,0x00, + + 19, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x08,0x00,0x63,0x10,0x00,0x63,0x10,0x00,0x63,0x20,0x00,0x63,0x2F,0x80,0x63,0x58,0xC0,0x3E,0x98,0xC0,0x00,0x98,0xC0,0x01,0x18,0xC0,0x01,0x18,0xC0,0x02,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x1E,0x60,0x36,0x60,0x63,0x60,0x61,0xC0,0x60,0xC0,0x30,0xE0,0x1F,0x30,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x27 ''' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x28 '(' + 0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18,0x0C,0x06, + + 8, // 0x29 ')' + 0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x30,0x60, + + 11, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x24,0x80,0x15,0x00,0x0E,0x00,0x15,0x00,0x24,0x80,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x3F,0xE0,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x60,0x60,0x60,0xC0,0xC0, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, + + 10, // 0x2F '/' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x00,0x00, + + 11, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x1E,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x1F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x60,0xC0,0x00,0xC0,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x60,0xC0,0x00,0xC0,0x01,0x80,0x0F,0x00,0x01,0x80,0x00,0xC0,0x60,0xC0,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x80,0x05,0x80,0x09,0x80,0x11,0x80,0x21,0x80,0x41,0x80,0x7F,0xE0,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xC0,0x30,0x00,0x30,0x00,0x30,0x00,0x3F,0x00,0x01,0x80,0x00,0xC0,0x00,0xC0,0x60,0xC0,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x18,0x00,0x30,0x00,0x60,0x00,0x6F,0x00,0x71,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0xC0,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0xC0,0x1E,0xC0,0x00,0xC0,0x01,0x80,0x03,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x38,0x30,0x30,0x30,0x60,0x60, + + 13, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x18,0x60,0x20,0x10,0x27,0xD0,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x27,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, + + 12, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x0F,0x00,0x0F,0x00,0x19,0x80,0x19,0x80,0x30,0xC0,0x3F,0xC0,0x30,0xC0,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0xC0,0x30,0xC0,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x30,0xC0,0x38,0xC0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0xC0,0x60,0xC0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0xC0,0x61,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC0,0x38,0x60,0x30,0x60,0x60,0x00,0x60,0x00,0x63,0xE0,0x60,0x60,0x60,0x60,0x30,0x60,0x38,0x60,0x0F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0xE0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00, + + 8, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x3E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0xF8,0x00,0x00,0x00, + + 12, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0xC0,0x61,0x80,0x63,0x00,0x66,0x00,0x6C,0x00,0x7E,0x00,0x73,0x00,0x61,0x80,0x60,0xC0,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x38,0x70,0x38,0x70,0x78,0x58,0x58,0x58,0xD8,0x4C,0x98,0x4D,0x98,0x47,0x18,0x47,0x18,0x42,0x18,0x40,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x20,0x70,0x20,0x58,0x20,0x4C,0x20,0x4C,0x20,0x46,0x20,0x43,0x20,0x43,0x20,0x41,0xA0,0x40,0xE0,0x40,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0xE0,0x30,0x60,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x30,0x60,0x38,0xE0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0xE0,0x30,0x60,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x30,0x60,0x38,0xE0,0x0F,0x80,0x03,0x00,0x03,0x80,0x01,0xF0, + + 12, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0x60,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x30,0xC0,0x60,0xC0,0x60,0x00,0x7C,0x00,0x3F,0x80,0x03,0xC0,0x00,0xC0,0x60,0xC0,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x54 'T' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0xC0,0x1F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x31,0x80,0x31,0x80,0x1B,0x00,0x1B,0x00,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 16, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x86,0x61,0x86,0x63,0xC6,0x33,0xCC,0x32,0x4C,0x32,0x4C,0x1E,0x78,0x1C,0x38,0x1C,0x38,0x0C,0x30,0x0C,0x30,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x31,0x80,0x31,0x80,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1B,0x00,0x31,0x80,0x31,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5B '[' + 0x00,0x00,0x00,0x3E,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3E, + + 10, // 0x5C '\' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x00,0x00, + + 8, // 0x5D ']' + 0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x7C, + + 13, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0F,0x00,0x19,0x80,0x30,0xC0,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xE0,0x00,0x00, + + 11, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x01,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x63,0x80,0x3D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x62 'b' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x33,0x60,0x60,0x60,0x60,0x33,0x1E,0x00,0x00,0x00, + + 10, // 0x64 'd' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x7F,0x80,0x60,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x00,0x00,0x1C,0x30,0x30,0x30,0x7C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, + + 10, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x03,0x00,0x3E,0x00, + + 10, // 0x68 'h' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x69 'i' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 6, // 0x6A 'j' + 0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF0, + + 10, // 0x6B 'k' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x61,0x80,0x63,0x00,0x66,0x00,0x6C,0x00,0x7E,0x00,0x73,0x00,0x61,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x6C 'l' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 16, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x3C,0x71,0xC6,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00, + + 10, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x01,0x80,0x01,0x80, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x7E,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 9, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x61,0x00,0x60,0x00,0x7E,0x00,0x3F,0x00,0x03,0x00,0x43,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x7E,0x30,0x30,0x30,0x30,0x30,0x30,0x1E,0x00,0x00,0x00, + + 10, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x80,0x3D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x63,0x18,0x37,0xB0,0x34,0xB0,0x3C,0xF0,0x18,0x60,0x18,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00, + + 9, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x80, + + 8, // 0x7C '|' + 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + + 11, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x01,0xC0,0x03,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x3C,0x00, + + 13, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x10,0x24,0x10,0x42,0x10,0x41,0x20,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 15, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + +} + diff --git a/src/agg_gsv_text.cpp b/src/agg_gsv_text.cpp new file mode 100644 index 0000000..01adfbf --- /dev/null +++ b/src/agg_gsv_text.cpp @@ -0,0 +1,677 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Class gsv_text +// +//---------------------------------------------------------------------------- +#include <cstring> +#include <cstdio> +#include "agg_gsv_text.h" +#include "agg_bounding_rect.h" + + + +namespace agg +{ + int8u gsv_default_font[] = + { + 0x40,0x00,0x6c,0x0f,0x15,0x00,0x0e,0x00,0xf9,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x0d,0x0a,0x0d,0x0a,0x46,0x6f,0x6e,0x74,0x20,0x28, + 0x63,0x29,0x20,0x4d,0x69,0x63,0x72,0x6f,0x50,0x72, + 0x6f,0x66,0x20,0x32,0x37,0x20,0x53,0x65,0x70,0x74, + 0x65,0x6d,0x62,0x2e,0x31,0x39,0x38,0x39,0x00,0x0d, + 0x0a,0x0d,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x00,0x12,0x00,0x34,0x00,0x46,0x00,0x94,0x00, + 0xd0,0x00,0x2e,0x01,0x3e,0x01,0x64,0x01,0x8a,0x01, + 0x98,0x01,0xa2,0x01,0xb4,0x01,0xba,0x01,0xc6,0x01, + 0xcc,0x01,0xf0,0x01,0xfa,0x01,0x18,0x02,0x38,0x02, + 0x44,0x02,0x68,0x02,0x98,0x02,0xa2,0x02,0xde,0x02, + 0x0e,0x03,0x24,0x03,0x40,0x03,0x48,0x03,0x52,0x03, + 0x5a,0x03,0x82,0x03,0xec,0x03,0xfa,0x03,0x26,0x04, + 0x4c,0x04,0x6a,0x04,0x7c,0x04,0x8a,0x04,0xb6,0x04, + 0xc4,0x04,0xca,0x04,0xe0,0x04,0xee,0x04,0xf8,0x04, + 0x0a,0x05,0x18,0x05,0x44,0x05,0x5e,0x05,0x8e,0x05, + 0xac,0x05,0xd6,0x05,0xe0,0x05,0xf6,0x05,0x00,0x06, + 0x12,0x06,0x1c,0x06,0x28,0x06,0x36,0x06,0x48,0x06, + 0x4e,0x06,0x60,0x06,0x6e,0x06,0x74,0x06,0x84,0x06, + 0xa6,0x06,0xc8,0x06,0xe6,0x06,0x08,0x07,0x2c,0x07, + 0x3c,0x07,0x68,0x07,0x7c,0x07,0x8c,0x07,0xa2,0x07, + 0xb0,0x07,0xb6,0x07,0xd8,0x07,0xec,0x07,0x10,0x08, + 0x32,0x08,0x54,0x08,0x64,0x08,0x88,0x08,0x98,0x08, + 0xac,0x08,0xb6,0x08,0xc8,0x08,0xd2,0x08,0xe4,0x08, + 0xf2,0x08,0x3e,0x09,0x48,0x09,0x94,0x09,0xc2,0x09, + 0xc4,0x09,0xd0,0x09,0xe2,0x09,0x04,0x0a,0x0e,0x0a, + 0x26,0x0a,0x34,0x0a,0x4a,0x0a,0x66,0x0a,0x70,0x0a, + 0x7e,0x0a,0x8e,0x0a,0x9a,0x0a,0xa6,0x0a,0xb4,0x0a, + 0xd8,0x0a,0xe2,0x0a,0xf6,0x0a,0x18,0x0b,0x22,0x0b, + 0x32,0x0b,0x56,0x0b,0x60,0x0b,0x6e,0x0b,0x7c,0x0b, + 0x8a,0x0b,0x9c,0x0b,0x9e,0x0b,0xb2,0x0b,0xc2,0x0b, + 0xd8,0x0b,0xf4,0x0b,0x08,0x0c,0x30,0x0c,0x56,0x0c, + 0x72,0x0c,0x90,0x0c,0xb2,0x0c,0xce,0x0c,0xe2,0x0c, + 0xfe,0x0c,0x10,0x0d,0x26,0x0d,0x36,0x0d,0x42,0x0d, + 0x4e,0x0d,0x5c,0x0d,0x78,0x0d,0x8c,0x0d,0x8e,0x0d, + 0x90,0x0d,0x92,0x0d,0x94,0x0d,0x96,0x0d,0x98,0x0d, + 0x9a,0x0d,0x9c,0x0d,0x9e,0x0d,0xa0,0x0d,0xa2,0x0d, + 0xa4,0x0d,0xa6,0x0d,0xa8,0x0d,0xaa,0x0d,0xac,0x0d, + 0xae,0x0d,0xb0,0x0d,0xb2,0x0d,0xb4,0x0d,0xb6,0x0d, + 0xb8,0x0d,0xba,0x0d,0xbc,0x0d,0xbe,0x0d,0xc0,0x0d, + 0xc2,0x0d,0xc4,0x0d,0xc6,0x0d,0xc8,0x0d,0xca,0x0d, + 0xcc,0x0d,0xce,0x0d,0xd0,0x0d,0xd2,0x0d,0xd4,0x0d, + 0xd6,0x0d,0xd8,0x0d,0xda,0x0d,0xdc,0x0d,0xde,0x0d, + 0xe0,0x0d,0xe2,0x0d,0xe4,0x0d,0xe6,0x0d,0xe8,0x0d, + 0xea,0x0d,0xec,0x0d,0x0c,0x0e,0x26,0x0e,0x48,0x0e, + 0x64,0x0e,0x88,0x0e,0x92,0x0e,0xa6,0x0e,0xb4,0x0e, + 0xd0,0x0e,0xee,0x0e,0x02,0x0f,0x16,0x0f,0x26,0x0f, + 0x3c,0x0f,0x58,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f, + 0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f, + 0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f, + 0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x10,0x80, + 0x05,0x95,0x00,0x72,0x00,0xfb,0xff,0x7f,0x01,0x7f, + 0x01,0x01,0xff,0x01,0x05,0xfe,0x05,0x95,0xff,0x7f, + 0x00,0x7a,0x01,0x86,0xff,0x7a,0x01,0x87,0x01,0x7f, + 0xfe,0x7a,0x0a,0x87,0xff,0x7f,0x00,0x7a,0x01,0x86, + 0xff,0x7a,0x01,0x87,0x01,0x7f,0xfe,0x7a,0x05,0xf2, + 0x0b,0x95,0xf9,0x64,0x0d,0x9c,0xf9,0x64,0xfa,0x91, + 0x0e,0x00,0xf1,0xfa,0x0e,0x00,0x04,0xfc,0x08,0x99, + 0x00,0x63,0x04,0x9d,0x00,0x63,0x04,0x96,0xff,0x7f, + 0x01,0x7f,0x01,0x01,0x00,0x01,0xfe,0x02,0xfd,0x01, + 0xfc,0x00,0xfd,0x7f,0xfe,0x7e,0x00,0x7e,0x01,0x7e, + 0x01,0x7f,0x02,0x7f,0x06,0x7e,0x02,0x7f,0x02,0x7e, + 0xf2,0x89,0x02,0x7e,0x02,0x7f,0x06,0x7e,0x02,0x7f, + 0x01,0x7f,0x01,0x7e,0x00,0x7c,0xfe,0x7e,0xfd,0x7f, + 0xfc,0x00,0xfd,0x01,0xfe,0x02,0x00,0x01,0x01,0x01, + 0x01,0x7f,0xff,0x7f,0x10,0xfd,0x15,0x95,0xee,0x6b, + 0x05,0x95,0x02,0x7e,0x00,0x7e,0xff,0x7e,0xfe,0x7f, + 0xfe,0x00,0xfe,0x02,0x00,0x02,0x01,0x02,0x02,0x01, + 0x02,0x00,0x02,0x7f,0x03,0x7f,0x03,0x00,0x03,0x01, + 0x02,0x01,0xfc,0xf2,0xfe,0x7f,0xff,0x7e,0x00,0x7e, + 0x02,0x7e,0x02,0x00,0x02,0x01,0x01,0x02,0x00,0x02, + 0xfe,0x02,0xfe,0x00,0x07,0xf9,0x15,0x8d,0xff,0x7f, + 0x01,0x7f,0x01,0x01,0x00,0x01,0xff,0x01,0xff,0x00, + 0xff,0x7f,0xff,0x7e,0xfe,0x7b,0xfe,0x7d,0xfe,0x7e, + 0xfe,0x7f,0xfd,0x00,0xfd,0x01,0xff,0x02,0x00,0x03, + 0x01,0x02,0x06,0x04,0x02,0x02,0x01,0x02,0x00,0x02, + 0xff,0x02,0xfe,0x01,0xfe,0x7f,0xff,0x7e,0x00,0x7e, + 0x01,0x7d,0x02,0x7d,0x05,0x79,0x02,0x7e,0x03,0x7f, + 0x01,0x00,0x01,0x01,0x00,0x01,0xf1,0xfe,0xfe,0x01, + 0xff,0x02,0x00,0x03,0x01,0x02,0x02,0x02,0x00,0x86, + 0x01,0x7e,0x08,0x75,0x02,0x7e,0x02,0x7f,0x05,0x80, + 0x05,0x93,0xff,0x01,0x01,0x01,0x01,0x7f,0x00,0x7e, + 0xff,0x7e,0xff,0x7f,0x06,0xf1,0x0b,0x99,0xfe,0x7e, + 0xfe,0x7d,0xfe,0x7c,0xff,0x7b,0x00,0x7c,0x01,0x7b, + 0x02,0x7c,0x02,0x7d,0x02,0x7e,0xfe,0x9e,0xfe,0x7c, + 0xff,0x7d,0xff,0x7b,0x00,0x7c,0x01,0x7b,0x01,0x7d, + 0x02,0x7c,0x05,0x85,0x03,0x99,0x02,0x7e,0x02,0x7d, + 0x02,0x7c,0x01,0x7b,0x00,0x7c,0xff,0x7b,0xfe,0x7c, + 0xfe,0x7d,0xfe,0x7e,0x02,0x9e,0x02,0x7c,0x01,0x7d, + 0x01,0x7b,0x00,0x7c,0xff,0x7b,0xff,0x7d,0xfe,0x7c, + 0x09,0x85,0x08,0x95,0x00,0x74,0xfb,0x89,0x0a,0x7a, + 0x00,0x86,0xf6,0x7a,0x0d,0xf4,0x0d,0x92,0x00,0x6e, + 0xf7,0x89,0x12,0x00,0x04,0xf7,0x06,0x81,0xff,0x7f, + 0xff,0x01,0x01,0x01,0x01,0x7f,0x00,0x7e,0xff,0x7e, + 0xff,0x7f,0x06,0x84,0x04,0x89,0x12,0x00,0x04,0xf7, + 0x05,0x82,0xff,0x7f,0x01,0x7f,0x01,0x01,0xff,0x01, + 0x05,0xfe,0x00,0xfd,0x0e,0x18,0x00,0xeb,0x09,0x95, + 0xfd,0x7f,0xfe,0x7d,0xff,0x7b,0x00,0x7d,0x01,0x7b, + 0x02,0x7d,0x03,0x7f,0x02,0x00,0x03,0x01,0x02,0x03, + 0x01,0x05,0x00,0x03,0xff,0x05,0xfe,0x03,0xfd,0x01, + 0xfe,0x00,0x0b,0xeb,0x06,0x91,0x02,0x01,0x03,0x03, + 0x00,0x6b,0x09,0x80,0x04,0x90,0x00,0x01,0x01,0x02, + 0x01,0x01,0x02,0x01,0x04,0x00,0x02,0x7f,0x01,0x7f, + 0x01,0x7e,0x00,0x7e,0xff,0x7e,0xfe,0x7d,0xf6,0x76, + 0x0e,0x00,0x03,0x80,0x05,0x95,0x0b,0x00,0xfa,0x78, + 0x03,0x00,0x02,0x7f,0x01,0x7f,0x01,0x7d,0x00,0x7e, + 0xff,0x7d,0xfe,0x7e,0xfd,0x7f,0xfd,0x00,0xfd,0x01, + 0xff,0x01,0xff,0x02,0x11,0xfc,0x0d,0x95,0xf6,0x72, + 0x0f,0x00,0xfb,0x8e,0x00,0x6b,0x07,0x80,0x0f,0x95, + 0xf6,0x00,0xff,0x77,0x01,0x01,0x03,0x01,0x03,0x00, + 0x03,0x7f,0x02,0x7e,0x01,0x7d,0x00,0x7e,0xff,0x7d, + 0xfe,0x7e,0xfd,0x7f,0xfd,0x00,0xfd,0x01,0xff,0x01, + 0xff,0x02,0x11,0xfc,0x10,0x92,0xff,0x02,0xfd,0x01, + 0xfe,0x00,0xfd,0x7f,0xfe,0x7d,0xff,0x7b,0x00,0x7b, + 0x01,0x7c,0x02,0x7e,0x03,0x7f,0x01,0x00,0x03,0x01, + 0x02,0x02,0x01,0x03,0x00,0x01,0xff,0x03,0xfe,0x02, + 0xfd,0x01,0xff,0x00,0xfd,0x7f,0xfe,0x7e,0xff,0x7d, + 0x10,0xf9,0x11,0x95,0xf6,0x6b,0xfc,0x95,0x0e,0x00, + 0x03,0xeb,0x08,0x95,0xfd,0x7f,0xff,0x7e,0x00,0x7e, + 0x01,0x7e,0x02,0x7f,0x04,0x7f,0x03,0x7f,0x02,0x7e, + 0x01,0x7e,0x00,0x7d,0xff,0x7e,0xff,0x7f,0xfd,0x7f, + 0xfc,0x00,0xfd,0x01,0xff,0x01,0xff,0x02,0x00,0x03, + 0x01,0x02,0x02,0x02,0x03,0x01,0x04,0x01,0x02,0x01, + 0x01,0x02,0x00,0x02,0xff,0x02,0xfd,0x01,0xfc,0x00, + 0x0c,0xeb,0x10,0x8e,0xff,0x7d,0xfe,0x7e,0xfd,0x7f, + 0xff,0x00,0xfd,0x01,0xfe,0x02,0xff,0x03,0x00,0x01, + 0x01,0x03,0x02,0x02,0x03,0x01,0x01,0x00,0x03,0x7f, + 0x02,0x7e,0x01,0x7c,0x00,0x7b,0xff,0x7b,0xfe,0x7d, + 0xfd,0x7f,0xfe,0x00,0xfd,0x01,0xff,0x02,0x10,0xfd, + 0x05,0x8e,0xff,0x7f,0x01,0x7f,0x01,0x01,0xff,0x01, + 0x00,0xf4,0xff,0x7f,0x01,0x7f,0x01,0x01,0xff,0x01, + 0x05,0xfe,0x05,0x8e,0xff,0x7f,0x01,0x7f,0x01,0x01, + 0xff,0x01,0x01,0xf3,0xff,0x7f,0xff,0x01,0x01,0x01, + 0x01,0x7f,0x00,0x7e,0xff,0x7e,0xff,0x7f,0x06,0x84, + 0x14,0x92,0xf0,0x77,0x10,0x77,0x04,0x80,0x04,0x8c, + 0x12,0x00,0xee,0xfa,0x12,0x00,0x04,0xfa,0x04,0x92, + 0x10,0x77,0xf0,0x77,0x14,0x80,0x03,0x90,0x00,0x01, + 0x01,0x02,0x01,0x01,0x02,0x01,0x04,0x00,0x02,0x7f, + 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xff,0x7e,0xff,0x7f, + 0xfc,0x7e,0x00,0x7d,0x00,0xfb,0xff,0x7f,0x01,0x7f, + 0x01,0x01,0xff,0x01,0x09,0xfe,0x12,0x8d,0xff,0x02, + 0xfe,0x01,0xfd,0x00,0xfe,0x7f,0xff,0x7f,0xff,0x7d, + 0x00,0x7d,0x01,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, + 0x01,0x02,0xfb,0x88,0xfe,0x7e,0xff,0x7d,0x00,0x7d, + 0x01,0x7e,0x01,0x7f,0x07,0x8b,0xff,0x78,0x00,0x7e, + 0x02,0x7f,0x02,0x00,0x02,0x02,0x01,0x03,0x00,0x02, + 0xff,0x03,0xff,0x02,0xfe,0x02,0xfe,0x01,0xfd,0x01, + 0xfd,0x00,0xfd,0x7f,0xfe,0x7f,0xfe,0x7e,0xff,0x7e, + 0xff,0x7d,0x00,0x7d,0x01,0x7d,0x01,0x7e,0x02,0x7e, + 0x02,0x7f,0x03,0x7f,0x03,0x00,0x03,0x01,0x02,0x01, + 0x01,0x01,0xfe,0x8d,0xff,0x78,0x00,0x7e,0x01,0x7f, + 0x08,0xfb,0x09,0x95,0xf8,0x6b,0x08,0x95,0x08,0x6b, + 0xf3,0x87,0x0a,0x00,0x04,0xf9,0x04,0x95,0x00,0x6b, + 0x00,0x95,0x09,0x00,0x03,0x7f,0x01,0x7f,0x01,0x7e, + 0x00,0x7e,0xff,0x7e,0xff,0x7f,0xfd,0x7f,0xf7,0x80, + 0x09,0x00,0x03,0x7f,0x01,0x7f,0x01,0x7e,0x00,0x7d, + 0xff,0x7e,0xff,0x7f,0xfd,0x7f,0xf7,0x00,0x11,0x80, + 0x12,0x90,0xff,0x02,0xfe,0x02,0xfe,0x01,0xfc,0x00, + 0xfe,0x7f,0xfe,0x7e,0xff,0x7e,0xff,0x7d,0x00,0x7b, + 0x01,0x7d,0x01,0x7e,0x02,0x7e,0x02,0x7f,0x04,0x00, + 0x02,0x01,0x02,0x02,0x01,0x02,0x03,0xfb,0x04,0x95, + 0x00,0x6b,0x00,0x95,0x07,0x00,0x03,0x7f,0x02,0x7e, + 0x01,0x7e,0x01,0x7d,0x00,0x7b,0xff,0x7d,0xff,0x7e, + 0xfe,0x7e,0xfd,0x7f,0xf9,0x00,0x11,0x80,0x04,0x95, + 0x00,0x6b,0x00,0x95,0x0d,0x00,0xf3,0xf6,0x08,0x00, + 0xf8,0xf5,0x0d,0x00,0x02,0x80,0x04,0x95,0x00,0x6b, + 0x00,0x95,0x0d,0x00,0xf3,0xf6,0x08,0x00,0x06,0xf5, + 0x12,0x90,0xff,0x02,0xfe,0x02,0xfe,0x01,0xfc,0x00, + 0xfe,0x7f,0xfe,0x7e,0xff,0x7e,0xff,0x7d,0x00,0x7b, + 0x01,0x7d,0x01,0x7e,0x02,0x7e,0x02,0x7f,0x04,0x00, + 0x02,0x01,0x02,0x02,0x01,0x02,0x00,0x03,0xfb,0x80, + 0x05,0x00,0x03,0xf8,0x04,0x95,0x00,0x6b,0x0e,0x95, + 0x00,0x6b,0xf2,0x8b,0x0e,0x00,0x04,0xf5,0x04,0x95, + 0x00,0x6b,0x04,0x80,0x0c,0x95,0x00,0x70,0xff,0x7d, + 0xff,0x7f,0xfe,0x7f,0xfe,0x00,0xfe,0x01,0xff,0x01, + 0xff,0x03,0x00,0x02,0x0e,0xf9,0x04,0x95,0x00,0x6b, + 0x0e,0x95,0xf2,0x72,0x05,0x85,0x09,0x74,0x03,0x80, + 0x04,0x95,0x00,0x6b,0x00,0x80,0x0c,0x00,0x01,0x80, + 0x04,0x95,0x00,0x6b,0x00,0x95,0x08,0x6b,0x08,0x95, + 0xf8,0x6b,0x08,0x95,0x00,0x6b,0x04,0x80,0x04,0x95, + 0x00,0x6b,0x00,0x95,0x0e,0x6b,0x00,0x95,0x00,0x6b, + 0x04,0x80,0x09,0x95,0xfe,0x7f,0xfe,0x7e,0xff,0x7e, + 0xff,0x7d,0x00,0x7b,0x01,0x7d,0x01,0x7e,0x02,0x7e, + 0x02,0x7f,0x04,0x00,0x02,0x01,0x02,0x02,0x01,0x02, + 0x01,0x03,0x00,0x05,0xff,0x03,0xff,0x02,0xfe,0x02, + 0xfe,0x01,0xfc,0x00,0x0d,0xeb,0x04,0x95,0x00,0x6b, + 0x00,0x95,0x09,0x00,0x03,0x7f,0x01,0x7f,0x01,0x7e, + 0x00,0x7d,0xff,0x7e,0xff,0x7f,0xfd,0x7f,0xf7,0x00, + 0x11,0xf6,0x09,0x95,0xfe,0x7f,0xfe,0x7e,0xff,0x7e, + 0xff,0x7d,0x00,0x7b,0x01,0x7d,0x01,0x7e,0x02,0x7e, + 0x02,0x7f,0x04,0x00,0x02,0x01,0x02,0x02,0x01,0x02, + 0x01,0x03,0x00,0x05,0xff,0x03,0xff,0x02,0xfe,0x02, + 0xfe,0x01,0xfc,0x00,0x03,0xef,0x06,0x7a,0x04,0x82, + 0x04,0x95,0x00,0x6b,0x00,0x95,0x09,0x00,0x03,0x7f, + 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xff,0x7e,0xff,0x7f, + 0xfd,0x7f,0xf7,0x00,0x07,0x80,0x07,0x75,0x03,0x80, + 0x11,0x92,0xfe,0x02,0xfd,0x01,0xfc,0x00,0xfd,0x7f, + 0xfe,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f,0x02,0x7f, + 0x06,0x7e,0x02,0x7f,0x01,0x7f,0x01,0x7e,0x00,0x7d, + 0xfe,0x7e,0xfd,0x7f,0xfc,0x00,0xfd,0x01,0xfe,0x02, + 0x11,0xfd,0x08,0x95,0x00,0x6b,0xf9,0x95,0x0e,0x00, + 0x01,0xeb,0x04,0x95,0x00,0x71,0x01,0x7d,0x02,0x7e, + 0x03,0x7f,0x02,0x00,0x03,0x01,0x02,0x02,0x01,0x03, + 0x00,0x0f,0x04,0xeb,0x01,0x95,0x08,0x6b,0x08,0x95, + 0xf8,0x6b,0x09,0x80,0x02,0x95,0x05,0x6b,0x05,0x95, + 0xfb,0x6b,0x05,0x95,0x05,0x6b,0x05,0x95,0xfb,0x6b, + 0x07,0x80,0x03,0x95,0x0e,0x6b,0x00,0x95,0xf2,0x6b, + 0x11,0x80,0x01,0x95,0x08,0x76,0x00,0x75,0x08,0x95, + 0xf8,0x76,0x09,0xf5,0x11,0x95,0xf2,0x6b,0x00,0x95, + 0x0e,0x00,0xf2,0xeb,0x0e,0x00,0x03,0x80,0x03,0x93, + 0x00,0x6c,0x01,0x94,0x00,0x6c,0xff,0x94,0x05,0x00, + 0xfb,0xec,0x05,0x00,0x02,0x81,0x00,0x95,0x0e,0x68, + 0x00,0x83,0x06,0x93,0x00,0x6c,0x01,0x94,0x00,0x6c, + 0xfb,0x94,0x05,0x00,0xfb,0xec,0x05,0x00,0x03,0x81, + 0x03,0x87,0x08,0x05,0x08,0x7b,0xf0,0x80,0x08,0x04, + 0x08,0x7c,0x03,0xf9,0x01,0x80,0x10,0x00,0x01,0x80, + 0x06,0x95,0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7f, + 0x01,0x01,0xff,0x01,0x05,0xef,0x0f,0x8e,0x00,0x72, + 0x00,0x8b,0xfe,0x02,0xfe,0x01,0xfd,0x00,0xfe,0x7f, + 0xfe,0x7e,0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e, + 0x02,0x7f,0x03,0x00,0x02,0x01,0x02,0x02,0x04,0xfd, + 0x04,0x95,0x00,0x6b,0x00,0x8b,0x02,0x02,0x02,0x01, + 0x03,0x00,0x02,0x7f,0x02,0x7e,0x01,0x7d,0x00,0x7e, + 0xff,0x7d,0xfe,0x7e,0xfe,0x7f,0xfd,0x00,0xfe,0x01, + 0xfe,0x02,0x0f,0xfd,0x0f,0x8b,0xfe,0x02,0xfe,0x01, + 0xfd,0x00,0xfe,0x7f,0xfe,0x7e,0xff,0x7d,0x00,0x7e, + 0x01,0x7d,0x02,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, + 0x02,0x02,0x03,0xfd,0x0f,0x95,0x00,0x6b,0x00,0x8b, + 0xfe,0x02,0xfe,0x01,0xfd,0x00,0xfe,0x7f,0xfe,0x7e, + 0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e,0x02,0x7f, + 0x03,0x00,0x02,0x01,0x02,0x02,0x04,0xfd,0x03,0x88, + 0x0c,0x00,0x00,0x02,0xff,0x02,0xff,0x01,0xfe,0x01, + 0xfd,0x00,0xfe,0x7f,0xfe,0x7e,0xff,0x7d,0x00,0x7e, + 0x01,0x7d,0x02,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, + 0x02,0x02,0x03,0xfd,0x0a,0x95,0xfe,0x00,0xfe,0x7f, + 0xff,0x7d,0x00,0x6f,0xfd,0x8e,0x07,0x00,0x03,0xf2, + 0x0f,0x8e,0x00,0x70,0xff,0x7d,0xff,0x7f,0xfe,0x7f, + 0xfd,0x00,0xfe,0x01,0x09,0x91,0xfe,0x02,0xfe,0x01, + 0xfd,0x00,0xfe,0x7f,0xfe,0x7e,0xff,0x7d,0x00,0x7e, + 0x01,0x7d,0x02,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, + 0x02,0x02,0x04,0xfd,0x04,0x95,0x00,0x6b,0x00,0x8a, + 0x03,0x03,0x02,0x01,0x03,0x00,0x02,0x7f,0x01,0x7d, + 0x00,0x76,0x04,0x80,0x03,0x95,0x01,0x7f,0x01,0x01, + 0xff,0x01,0xff,0x7f,0x01,0xf9,0x00,0x72,0x04,0x80, + 0x05,0x95,0x01,0x7f,0x01,0x01,0xff,0x01,0xff,0x7f, + 0x01,0xf9,0x00,0x6f,0xff,0x7d,0xfe,0x7f,0xfe,0x00, + 0x09,0x87,0x04,0x95,0x00,0x6b,0x0a,0x8e,0xf6,0x76, + 0x04,0x84,0x07,0x78,0x02,0x80,0x04,0x95,0x00,0x6b, + 0x04,0x80,0x04,0x8e,0x00,0x72,0x00,0x8a,0x03,0x03, + 0x02,0x01,0x03,0x00,0x02,0x7f,0x01,0x7d,0x00,0x76, + 0x00,0x8a,0x03,0x03,0x02,0x01,0x03,0x00,0x02,0x7f, + 0x01,0x7d,0x00,0x76,0x04,0x80,0x04,0x8e,0x00,0x72, + 0x00,0x8a,0x03,0x03,0x02,0x01,0x03,0x00,0x02,0x7f, + 0x01,0x7d,0x00,0x76,0x04,0x80,0x08,0x8e,0xfe,0x7f, + 0xfe,0x7e,0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e, + 0x02,0x7f,0x03,0x00,0x02,0x01,0x02,0x02,0x01,0x03, + 0x00,0x02,0xff,0x03,0xfe,0x02,0xfe,0x01,0xfd,0x00, + 0x0b,0xf2,0x04,0x8e,0x00,0x6b,0x00,0x92,0x02,0x02, + 0x02,0x01,0x03,0x00,0x02,0x7f,0x02,0x7e,0x01,0x7d, + 0x00,0x7e,0xff,0x7d,0xfe,0x7e,0xfe,0x7f,0xfd,0x00, + 0xfe,0x01,0xfe,0x02,0x0f,0xfd,0x0f,0x8e,0x00,0x6b, + 0x00,0x92,0xfe,0x02,0xfe,0x01,0xfd,0x00,0xfe,0x7f, + 0xfe,0x7e,0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e, + 0x02,0x7f,0x03,0x00,0x02,0x01,0x02,0x02,0x04,0xfd, + 0x04,0x8e,0x00,0x72,0x00,0x88,0x01,0x03,0x02,0x02, + 0x02,0x01,0x03,0x00,0x01,0xf2,0x0e,0x8b,0xff,0x02, + 0xfd,0x01,0xfd,0x00,0xfd,0x7f,0xff,0x7e,0x01,0x7e, + 0x02,0x7f,0x05,0x7f,0x02,0x7f,0x01,0x7e,0x00,0x7f, + 0xff,0x7e,0xfd,0x7f,0xfd,0x00,0xfd,0x01,0xff,0x02, + 0x0e,0xfd,0x05,0x95,0x00,0x6f,0x01,0x7d,0x02,0x7f, + 0x02,0x00,0xf8,0x8e,0x07,0x00,0x03,0xf2,0x04,0x8e, + 0x00,0x76,0x01,0x7d,0x02,0x7f,0x03,0x00,0x02,0x01, + 0x03,0x03,0x00,0x8a,0x00,0x72,0x04,0x80,0x02,0x8e, + 0x06,0x72,0x06,0x8e,0xfa,0x72,0x08,0x80,0x03,0x8e, + 0x04,0x72,0x04,0x8e,0xfc,0x72,0x04,0x8e,0x04,0x72, + 0x04,0x8e,0xfc,0x72,0x07,0x80,0x03,0x8e,0x0b,0x72, + 0x00,0x8e,0xf5,0x72,0x0e,0x80,0x02,0x8e,0x06,0x72, + 0x06,0x8e,0xfa,0x72,0xfe,0x7c,0xfe,0x7e,0xfe,0x7f, + 0xff,0x00,0x0f,0x87,0x0e,0x8e,0xf5,0x72,0x00,0x8e, + 0x0b,0x00,0xf5,0xf2,0x0b,0x00,0x03,0x80,0x09,0x99, + 0xfe,0x7f,0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7e, + 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xfe,0x7e,0x01,0x8e, + 0xff,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f,0x01,0x7e, + 0x00,0x7e,0xff,0x7e,0xfc,0x7e,0x04,0x7e,0x01,0x7e, + 0x00,0x7e,0xff,0x7e,0xff,0x7f,0xff,0x7e,0x00,0x7e, + 0x01,0x7e,0xff,0x8e,0x02,0x7e,0x00,0x7e,0xff,0x7e, + 0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f, + 0x02,0x7f,0x05,0x87,0x04,0x95,0x00,0x77,0x00,0xfd, + 0x00,0x77,0x04,0x80,0x05,0x99,0x02,0x7f,0x01,0x7f, + 0x01,0x7e,0x00,0x7e,0xff,0x7e,0xff,0x7f,0xff,0x7e, + 0x00,0x7e,0x02,0x7e,0xff,0x8e,0x01,0x7e,0x00,0x7e, + 0xff,0x7e,0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7e, + 0x04,0x7e,0xfc,0x7e,0xff,0x7e,0x00,0x7e,0x01,0x7e, + 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xff,0x7e,0x01,0x8e, + 0xfe,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f,0x01,0x7e, + 0x00,0x7e,0xff,0x7e,0xff,0x7f,0xfe,0x7f,0x09,0x87, + 0x03,0x86,0x00,0x02,0x01,0x03,0x02,0x01,0x02,0x00, + 0x02,0x7f,0x04,0x7d,0x02,0x7f,0x02,0x00,0x02,0x01, + 0x01,0x02,0xee,0xfe,0x01,0x02,0x02,0x01,0x02,0x00, + 0x02,0x7f,0x04,0x7d,0x02,0x7f,0x02,0x00,0x02,0x01, + 0x01,0x03,0x00,0x02,0x03,0xf4,0x10,0x80,0x03,0x80, + 0x07,0x15,0x08,0x6b,0xfe,0x85,0xf5,0x00,0x10,0xfb, + 0x0d,0x95,0xf6,0x00,0x00,0x6b,0x0a,0x00,0x02,0x02, + 0x00,0x08,0xfe,0x02,0xf6,0x00,0x0e,0xf4,0x03,0x80, + 0x00,0x15,0x0a,0x00,0x02,0x7e,0x00,0x7e,0x00,0x7d, + 0x00,0x7e,0xfe,0x7f,0xf6,0x00,0x0a,0x80,0x02,0x7e, + 0x01,0x7e,0x00,0x7d,0xff,0x7d,0xfe,0x7f,0xf6,0x00, + 0x10,0x80,0x03,0x80,0x00,0x15,0x0c,0x00,0xff,0x7e, + 0x03,0xed,0x03,0xfd,0x00,0x03,0x02,0x00,0x00,0x12, + 0x02,0x03,0x0a,0x00,0x00,0x6b,0x02,0x00,0x00,0x7d, + 0xfe,0x83,0xf4,0x00,0x11,0x80,0x0f,0x80,0xf4,0x00, + 0x00,0x15,0x0c,0x00,0xff,0xf6,0xf5,0x00,0x0f,0xf5, + 0x04,0x95,0x07,0x76,0x00,0x0a,0x07,0x80,0xf9,0x76, + 0x00,0x75,0xf8,0x80,0x07,0x0c,0x09,0xf4,0xf9,0x0c, + 0x09,0xf4,0x03,0x92,0x02,0x03,0x07,0x00,0x03,0x7d, + 0x00,0x7b,0xfc,0x7e,0x04,0x7d,0x00,0x7a,0xfd,0x7e, + 0xf9,0x00,0xfe,0x02,0x06,0x89,0x02,0x00,0x06,0xf5, + 0x03,0x95,0x00,0x6b,0x0c,0x15,0x00,0x6b,0x02,0x80, + 0x03,0x95,0x00,0x6b,0x0c,0x15,0x00,0x6b,0xf8,0x96, + 0x03,0x00,0x07,0xea,0x03,0x80,0x00,0x15,0x0c,0x80, + 0xf7,0x76,0xfd,0x00,0x03,0x80,0x0a,0x75,0x03,0x80, + 0x03,0x80,0x07,0x13,0x02,0x02,0x03,0x00,0x00,0x6b, + 0x02,0x80,0x03,0x80,0x00,0x15,0x09,0x6b,0x09,0x15, + 0x00,0x6b,0x03,0x80,0x03,0x80,0x00,0x15,0x00,0xf6, + 0x0d,0x00,0x00,0x8a,0x00,0x6b,0x03,0x80,0x07,0x80, + 0xfd,0x00,0xff,0x03,0x00,0x04,0x00,0x07,0x00,0x04, + 0x01,0x02,0x03,0x01,0x06,0x00,0x03,0x7f,0x01,0x7e, + 0x01,0x7c,0x00,0x79,0xff,0x7c,0xff,0x7d,0xfd,0x00, + 0xfa,0x00,0x0e,0x80,0x03,0x80,0x00,0x15,0x0c,0x00, + 0x00,0x6b,0x02,0x80,0x03,0x80,0x00,0x15,0x0a,0x00, + 0x02,0x7f,0x01,0x7d,0x00,0x7b,0xff,0x7e,0xfe,0x7f, + 0xf6,0x00,0x10,0xf7,0x11,0x8f,0xff,0x03,0xff,0x02, + 0xfe,0x01,0xfa,0x00,0xfd,0x7f,0xff,0x7e,0x00,0x7c, + 0x00,0x79,0x00,0x7b,0x01,0x7e,0x03,0x00,0x06,0x00, + 0x02,0x00,0x01,0x03,0x01,0x02,0x03,0xfb,0x03,0x95, + 0x0c,0x00,0xfa,0x80,0x00,0x6b,0x09,0x80,0x03,0x95, + 0x00,0x77,0x06,0x7a,0x06,0x06,0x00,0x09,0xfa,0xf1, + 0xfa,0x7a,0x0e,0x80,0x03,0x87,0x00,0x0b,0x02,0x02, + 0x03,0x00,0x02,0x7e,0x01,0x02,0x04,0x00,0x02,0x7e, + 0x00,0x75,0xfe,0x7e,0xfc,0x00,0xff,0x01,0xfe,0x7f, + 0xfd,0x00,0xfe,0x02,0x07,0x8e,0x00,0x6b,0x09,0x80, + 0x03,0x80,0x0e,0x15,0xf2,0x80,0x0e,0x6b,0x03,0x80, + 0x03,0x95,0x00,0x6b,0x0e,0x00,0x00,0x7d,0xfe,0x98, + 0x00,0x6b,0x05,0x80,0x03,0x95,0x00,0x75,0x02,0x7d, + 0x0a,0x00,0x00,0x8e,0x00,0x6b,0x02,0x80,0x03,0x95, + 0x00,0x6b,0x10,0x00,0x00,0x15,0xf8,0x80,0x00,0x6b, + 0x0a,0x80,0x03,0x95,0x00,0x6b,0x10,0x00,0x00,0x15, + 0xf8,0x80,0x00,0x6b,0x0a,0x00,0x00,0x7d,0x02,0x83, + 0x10,0x80,0x03,0x95,0x00,0x6b,0x09,0x00,0x03,0x02, + 0x00,0x08,0xfd,0x02,0xf7,0x00,0x0e,0x89,0x00,0x6b, + 0x03,0x80,0x03,0x95,0x00,0x6b,0x09,0x00,0x03,0x02, + 0x00,0x08,0xfd,0x02,0xf7,0x00,0x0e,0xf4,0x03,0x92, + 0x02,0x03,0x07,0x00,0x03,0x7d,0x00,0x70,0xfd,0x7e, + 0xf9,0x00,0xfe,0x02,0x03,0x89,0x09,0x00,0x02,0xf5, + 0x03,0x80,0x00,0x15,0x00,0xf5,0x07,0x00,0x00,0x08, + 0x02,0x03,0x06,0x00,0x02,0x7d,0x00,0x70,0xfe,0x7e, + 0xfa,0x00,0xfe,0x02,0x00,0x08,0x0c,0xf6,0x0f,0x80, + 0x00,0x15,0xf6,0x00,0xfe,0x7d,0x00,0x79,0x02,0x7e, + 0x0a,0x00,0xf4,0xf7,0x07,0x09,0x07,0xf7,0x03,0x8c, + 0x01,0x02,0x01,0x01,0x05,0x00,0x02,0x7f,0x01,0x7e, + 0x00,0x74,0x00,0x86,0xff,0x01,0xfe,0x01,0xfb,0x00, + 0xff,0x7f,0xff,0x7f,0x00,0x7c,0x01,0x7e,0x01,0x00, + 0x05,0x00,0x02,0x00,0x01,0x02,0x03,0xfe,0x04,0x8e, + 0x02,0x01,0x04,0x00,0x02,0x7f,0x01,0x7e,0x00,0x77, + 0xff,0x7e,0xfe,0x7f,0xfc,0x00,0xfe,0x01,0xff,0x02, + 0x00,0x09,0x01,0x02,0x02,0x02,0x03,0x01,0x02,0x01, + 0x01,0x01,0x01,0x02,0x02,0xeb,0x03,0x80,0x00,0x15, + 0x03,0x00,0x02,0x7e,0x00,0x7b,0xfe,0x7e,0xfd,0x00, + 0x03,0x80,0x04,0x00,0x03,0x7e,0x00,0x78,0xfd,0x7e, + 0xf9,0x00,0x0c,0x80,0x03,0x8c,0x02,0x02,0x02,0x01, + 0x03,0x00,0x02,0x7f,0x01,0x7d,0xfe,0x7e,0xf9,0x7d, + 0xff,0x7e,0x00,0x7d,0x03,0x7f,0x02,0x00,0x03,0x01, + 0x02,0x01,0x02,0xfe,0x0d,0x8c,0xff,0x02,0xfe,0x01, + 0xfc,0x00,0xfe,0x7f,0xff,0x7e,0x00,0x77,0x01,0x7e, + 0x02,0x7f,0x04,0x00,0x02,0x01,0x01,0x02,0x00,0x0f, + 0xff,0x02,0xfe,0x01,0xf9,0x00,0x0c,0xeb,0x03,0x88, + 0x0a,0x00,0x00,0x02,0x00,0x03,0xfe,0x02,0xfa,0x00, + 0xff,0x7e,0xff,0x7d,0x00,0x7b,0x01,0x7c,0x01,0x7f, + 0x06,0x00,0x02,0x02,0x03,0xfe,0x03,0x8f,0x06,0x77, + 0x06,0x09,0xfa,0x80,0x00,0x71,0xff,0x87,0xfb,0x79, + 0x07,0x87,0x05,0x79,0x02,0x80,0x03,0x8d,0x02,0x02, + 0x06,0x00,0x02,0x7e,0x00,0x7d,0xfc,0x7d,0x04,0x7e, + 0x00,0x7d,0xfe,0x7e,0xfa,0x00,0xfe,0x02,0x04,0x85, + 0x02,0x00,0x06,0xf9,0x03,0x8f,0x00,0x73,0x01,0x7e, + 0x07,0x00,0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e, + 0x03,0x80,0x03,0x8f,0x00,0x73,0x01,0x7e,0x07,0x00, + 0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e,0xf8,0x90, + 0x03,0x00,0x08,0xf0,0x03,0x80,0x00,0x15,0x00,0xf3, + 0x02,0x00,0x06,0x07,0xfa,0xf9,0x07,0x78,0x03,0x80, + 0x03,0x80,0x04,0x0c,0x02,0x03,0x04,0x00,0x00,0x71, + 0x02,0x80,0x03,0x80,0x00,0x0f,0x06,0x77,0x06,0x09, + 0x00,0x71,0x02,0x80,0x03,0x80,0x00,0x0f,0x0a,0xf1, + 0x00,0x0f,0xf6,0xf8,0x0a,0x00,0x02,0xf9,0x05,0x80, + 0xff,0x01,0xff,0x04,0x00,0x05,0x01,0x03,0x01,0x02, + 0x06,0x00,0x02,0x7e,0x00,0x7d,0x00,0x7b,0x00,0x7c, + 0xfe,0x7f,0xfa,0x00,0x0b,0x80,0x03,0x80,0x00,0x0f, + 0x00,0xfb,0x01,0x03,0x01,0x02,0x05,0x00,0x02,0x7e, + 0x01,0x7d,0x00,0x76,0x03,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x0a,0x8f,0x02,0x7f,0x01,0x7e,0x00,0x76, + 0xff,0x7f,0xfe,0x7f,0xfb,0x00,0xff,0x01,0xff,0x01, + 0x00,0x0a,0x01,0x02,0x01,0x01,0x05,0x00,0xf9,0x80, + 0x00,0x6b,0x0c,0x86,0x0d,0x8a,0xff,0x03,0xfe,0x02, + 0xfb,0x00,0xff,0x7e,0xff,0x7d,0x00,0x7b,0x01,0x7c, + 0x01,0x7f,0x05,0x00,0x02,0x01,0x01,0x03,0x03,0xfc, + 0x03,0x80,0x00,0x0f,0x00,0xfb,0x01,0x03,0x01,0x02, + 0x04,0x00,0x01,0x7e,0x01,0x7d,0x00,0x76,0x00,0x8a, + 0x01,0x03,0x02,0x02,0x03,0x00,0x02,0x7e,0x01,0x7d, + 0x00,0x76,0x03,0x80,0x03,0x8f,0x00,0x74,0x01,0x7e, + 0x02,0x7f,0x04,0x00,0x02,0x01,0x01,0x01,0x00,0x8d, + 0x00,0x6e,0xff,0x7e,0xfe,0x7f,0xfb,0x00,0xfe,0x01, + 0x0c,0x85,0x03,0x8d,0x01,0x02,0x03,0x00,0x02,0x7e, + 0x01,0x02,0x03,0x00,0x02,0x7e,0x00,0x74,0xfe,0x7f, + 0xfd,0x00,0xff,0x01,0xfe,0x7f,0xfd,0x00,0xff,0x01, + 0x00,0x0c,0x06,0x82,0x00,0x6b,0x08,0x86,0x03,0x80, + 0x0a,0x0f,0xf6,0x80,0x0a,0x71,0x03,0x80,0x03,0x8f, + 0x00,0x73,0x01,0x7e,0x07,0x00,0x02,0x02,0x00,0x0d, + 0x00,0xf3,0x01,0x7e,0x00,0x7e,0x03,0x82,0x03,0x8f, + 0x00,0x79,0x02,0x7e,0x08,0x00,0x00,0x89,0x00,0x71, + 0x02,0x80,0x03,0x8f,0x00,0x73,0x01,0x7e,0x03,0x00, + 0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e,0x03,0x00, + 0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e,0x03,0x80, + 0x03,0x8f,0x00,0x73,0x01,0x7e,0x03,0x00,0x02,0x02, + 0x00,0x0d,0x00,0xf3,0x01,0x7e,0x03,0x00,0x02,0x02, + 0x00,0x0d,0x00,0xf3,0x01,0x7e,0x00,0x7e,0x03,0x82, + 0x03,0x8d,0x00,0x02,0x02,0x00,0x00,0x71,0x08,0x00, + 0x02,0x02,0x00,0x06,0xfe,0x02,0xf8,0x00,0x0c,0xf6, + 0x03,0x8f,0x00,0x71,0x07,0x00,0x02,0x02,0x00,0x06, + 0xfe,0x02,0xf9,0x00,0x0c,0x85,0x00,0x71,0x02,0x80, + 0x03,0x8f,0x00,0x71,0x07,0x00,0x03,0x02,0x00,0x06, + 0xfd,0x02,0xf9,0x00,0x0c,0xf6,0x03,0x8d,0x02,0x02, + 0x06,0x00,0x02,0x7e,0x00,0x75,0xfe,0x7e,0xfa,0x00, + 0xfe,0x02,0x04,0x85,0x06,0x00,0x02,0xf9,0x03,0x80, + 0x00,0x0f,0x00,0xf8,0x04,0x00,0x00,0x06,0x02,0x02, + 0x04,0x00,0x02,0x7e,0x00,0x75,0xfe,0x7e,0xfc,0x00, + 0xfe,0x02,0x00,0x05,0x0a,0xf9,0x0d,0x80,0x00,0x0f, + 0xf7,0x00,0xff,0x7e,0x00,0x7b,0x01,0x7e,0x09,0x00, + 0xf6,0xfa,0x04,0x06,0x08,0xfa + }; + + //------------------------------------------------------------------------- + gsv_text::gsv_text() : + m_x(0.0), + m_y(0.0), + m_start_x(0.0), + m_width(10.0), + m_height(0.0), + m_space(0.0), + m_line_space(0.0), + m_text(m_chr), + m_text_buf(), + m_cur_chr(m_chr), + m_font(gsv_default_font), + m_loaded_font(), + m_status(initial), + m_big_endian(false), + m_flip(false) + { + m_chr[0] = m_chr[1] = 0; + + int t = 1; + if(*(char*)&t == 0) m_big_endian = true; + } + + //------------------------------------------------------------------------- + void gsv_text::font(const void* font) + { + m_font = font; + if(m_font == 0) m_font = &m_loaded_font[0]; + } + + //------------------------------------------------------------------------- + void gsv_text::size(double height, double width) + { + m_height = height; + m_width = width; + } + + //------------------------------------------------------------------------- + void gsv_text::space(double space) + { + m_space = space; + } + + //------------------------------------------------------------------------- + void gsv_text::line_space(double line_space) + { + m_line_space = line_space; + } + + //------------------------------------------------------------------------- + void gsv_text::start_point(double x, double y) + { + m_x = m_start_x = x; + m_y = y; + //if(m_flip) m_y += m_height; + } + + //------------------------------------------------------------------------- + void gsv_text::load_font(const char* file) + { + m_loaded_font.resize(0); + FILE* fd = std::fopen(file, "rb"); + if(fd) + { + unsigned len; + + std::fseek(fd, 0l, SEEK_END); + len = std::ftell(fd); + std::fseek(fd, 0l, SEEK_SET); + if(len > 0) + { + m_loaded_font.resize(len); + if (std::fread(&m_loaded_font[0], 1, len, fd) == len) + m_font = &m_loaded_font[0]; + else + m_font = 0; + } + std::fclose(fd); + } + } + + //------------------------------------------------------------------------- + void gsv_text::text(const char* text) + { + if(text == 0) + { + m_chr[0] = 0; + m_text = m_chr; + return; + } + unsigned new_size = std::strlen(text) + 1; + if(new_size > m_text_buf.size()) + { + m_text_buf.resize(new_size); + } + std::memcpy(&m_text_buf[0], text, new_size); + m_text = &m_text_buf[0]; + } + + //------------------------------------------------------------------------- + void gsv_text::rewind(unsigned) + { + m_status = initial; + if(m_font == 0) return; + + m_indices = (int8u*)m_font; + double base_height = value(m_indices + 4); + m_indices += value(m_indices); + m_glyphs = (int8*)(m_indices + 257*2); + m_h = m_height / base_height; + m_w = (m_width == 0.0) ? m_h : m_width / base_height; + if(m_flip) m_h = -m_h; + m_cur_chr = m_text; + } + + //------------------------------------------------------------------------- + unsigned gsv_text::vertex(double* x, double* y) + { + unsigned idx; + int8 yc, yf; + int dx, dy; + bool quit = false; + + while(!quit) + { + switch(m_status) + { + case initial: + if(m_font == 0) + { + quit = true; + break; + } + m_status = next_char; + + case next_char: + if(*m_cur_chr == 0) + { + quit = true; + break; + } + idx = (*m_cur_chr++) & 0xFF; + if(idx == '\n') + { + m_x = m_start_x; + m_y -= m_flip ? -m_height - m_line_space : m_height + m_line_space; + break; + } + idx <<= 1; + m_bglyph = m_glyphs + value(m_indices + idx); + m_eglyph = m_glyphs + value(m_indices + idx + 2); + m_status = start_glyph; + + case start_glyph: + *x = m_x; + *y = m_y; + m_status = glyph; + return path_cmd_move_to; + + case glyph: + if(m_bglyph >= m_eglyph) + { + m_status = next_char; + m_x += m_space; + break; + } + dx = int(*m_bglyph++); + yf = (yc = *m_bglyph++) & 0x80; + yc <<= 1; + yc >>= 1; + dy = int(yc); + m_x += double(dx) * m_w; + m_y += double(dy) * m_h; + *x = m_x; + *y = m_y; + return yf ? path_cmd_move_to : path_cmd_line_to; + } + + } + return path_cmd_stop; + } + + //------------------------------------------------------------------------- + double gsv_text::text_width() + { + double x1, y1, x2, y2; + bounding_rect_single(*this, 0, &x1, &y1, &x2, &y2); + return x2 - x1; + } + + +} diff --git a/src/agg_image_filters.cpp b/src/agg_image_filters.cpp new file mode 100644 index 0000000..549d9ad --- /dev/null +++ b/src/agg_image_filters.cpp @@ -0,0 +1,103 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Filtering class image_filter_lut implemantation +// +//---------------------------------------------------------------------------- + + +#include "agg_image_filters.h" + + +namespace agg +{ + //-------------------------------------------------------------------- + void image_filter_lut::realloc_lut(double radius) + { + m_radius = radius; + m_diameter = uceil(radius) * 2; + m_start = -int(m_diameter / 2 - 1); + unsigned size = m_diameter << image_subpixel_shift; + if(size > m_weight_array.size()) + { + m_weight_array.resize(size); + } + } + + + + //-------------------------------------------------------------------- + // This function normalizes integer values and corrects the rounding + // errors. It doesn't do anything with the source floating point values + // (m_weight_array_dbl), it corrects only integers according to the rule + // of 1.0 which means that any sum of pixel weights must be equal to 1.0. + // So, the filter function must produce a graph of the proper shape. + //-------------------------------------------------------------------- + void image_filter_lut::normalize() + { + unsigned i; + int flip = 1; + + for(i = 0; i < image_subpixel_scale; i++) + { + for(;;) + { + int sum = 0; + unsigned j; + for(j = 0; j < m_diameter; j++) + { + sum += m_weight_array[j * image_subpixel_scale + i]; + } + + if(sum == image_filter_scale) break; + + double k = double(image_filter_scale) / double(sum); + sum = 0; + for(j = 0; j < m_diameter; j++) + { + sum += m_weight_array[j * image_subpixel_scale + i] = + iround(m_weight_array[j * image_subpixel_scale + i] * k); + } + + sum -= image_filter_scale; + int inc = (sum > 0) ? -1 : 1; + + for(j = 0; j < m_diameter && sum; j++) + { + flip ^= 1; + unsigned idx = flip ? m_diameter/2 + j/2 : m_diameter/2 - j/2; + int v = m_weight_array[idx * image_subpixel_scale + i]; + if(v < image_filter_scale) + { + m_weight_array[idx * image_subpixel_scale + i] += inc; + sum += inc; + } + } + } + } + + unsigned pivot = m_diameter << (image_subpixel_shift - 1); + + for(i = 0; i < pivot; i++) + { + m_weight_array[pivot + i] = m_weight_array[pivot - i]; + } + unsigned end = (diameter() << image_subpixel_shift) - 1; + m_weight_array[0] = m_weight_array[end]; + } + + +} + diff --git a/src/agg_line_aa_basics.cpp b/src/agg_line_aa_basics.cpp new file mode 100644 index 0000000..8514f1b --- /dev/null +++ b/src/agg_line_aa_basics.cpp @@ -0,0 +1,82 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include <cmath> +#include "agg_line_aa_basics.h" + +namespace agg +{ + //------------------------------------------------------------------------- + // The number of the octant is determined as a 3-bit value as follows: + // bit 0 = vertical flag + // bit 1 = sx < 0 + // bit 2 = sy < 0 + // + // [N] shows the number of the orthogonal quadrant + // <M> shows the number of the diagonal quadrant + // <1> + // [1] | [0] + // . (3)011 | 001(1) . + // . | . + // . | . + // . | . + // (2)010 .|. 000(0) + // <2> ----------.+.----------- <0> + // (6)110 . | . 100(4) + // . | . + // . | . + // . | . + // (7)111 | 101(5) + // [2] | [3] + // <3> + // 0,1,2,3,4,5,6,7 + const int8u line_parameters::s_orthogonal_quadrant[8] = { 0,0,1,1,3,3,2,2 }; + const int8u line_parameters::s_diagonal_quadrant[8] = { 0,1,2,1,0,3,2,3 }; + + + + //------------------------------------------------------------------------- + void bisectrix(const line_parameters& l1, + const line_parameters& l2, + int* x, int* y) + { + double k = double(l2.len) / double(l1.len); + double tx = l2.x2 - (l2.x1 - l1.x1) * k; + double ty = l2.y2 - (l2.y1 - l1.y1) * k; + + //All bisectrices must be on the right of the line + //If the next point is on the left (l1 => l2.2) + //then the bisectix should be rotated by 180 degrees. + if(double(l2.x2 - l2.x1) * double(l2.y1 - l1.y1) < + double(l2.y2 - l2.y1) * double(l2.x1 - l1.x1) + 100.0) + { + tx -= (tx - l2.x1) * 2.0; + ty -= (ty - l2.y1) * 2.0; + } + + // Check if the bisectrix is too short + double dx = tx - l2.x1; + double dy = ty - l2.y1; + if((int)std::sqrt(dx * dx + dy * dy) < line_subpixel_scale) + { + *x = (l2.x1 + l2.x1 + (l2.y1 - l1.y1) + (l2.y2 - l2.y1)) >> 1; + *y = (l2.y1 + l2.y1 - (l2.x1 - l1.x1) - (l2.x2 - l2.x1)) >> 1; + return; + } + *x = iround(tx); + *y = iround(ty); + } + +} diff --git a/src/agg_line_profile_aa.cpp b/src/agg_line_profile_aa.cpp new file mode 100644 index 0000000..6066662 --- /dev/null +++ b/src/agg_line_profile_aa.cpp @@ -0,0 +1,116 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include "agg_renderer_outline_aa.h" + +namespace agg +{ + + //--------------------------------------------------------------------- + void line_profile_aa::width(double w) + { + if(w < 0.0) w = 0.0; + + if(w < m_smoother_width) w += w; + else w += m_smoother_width; + + w *= 0.5; + + w -= m_smoother_width; + double s = m_smoother_width; + if(w < 0.0) + { + s += w; + w = 0.0; + } + set(w, s); + } + + + //--------------------------------------------------------------------- + line_profile_aa::value_type* line_profile_aa::profile(double w) + { + m_subpixel_width = uround(w * subpixel_scale); + unsigned size = m_subpixel_width + subpixel_scale * 6; + if(size > m_profile.size()) + { + m_profile.resize(size); + } + return &m_profile[0]; + } + + + //--------------------------------------------------------------------- + void line_profile_aa::set(double center_width, double smoother_width) + { + double base_val = 1.0; + if(center_width == 0.0) center_width = 1.0 / subpixel_scale; + if(smoother_width == 0.0) smoother_width = 1.0 / subpixel_scale; + + double width = center_width + smoother_width; + if(width < m_min_width) + { + double k = width / m_min_width; + base_val *= k; + center_width /= k; + smoother_width /= k; + } + + value_type* ch = profile(center_width + smoother_width); + + unsigned subpixel_center_width = unsigned(center_width * subpixel_scale); + unsigned subpixel_smoother_width = unsigned(smoother_width * subpixel_scale); + + value_type* ch_center = ch + subpixel_scale*2; + value_type* ch_smoother = ch_center + subpixel_center_width; + + unsigned i; + + unsigned val = m_gamma[unsigned(base_val * aa_mask)]; + ch = ch_center; + for(i = 0; i < subpixel_center_width; i++) + { + *ch++ = (value_type)val; + } + + for(i = 0; i < subpixel_smoother_width; i++) + { + *ch_smoother++ = + m_gamma[unsigned((base_val - + base_val * + (double(i) / subpixel_smoother_width)) * aa_mask)]; + } + + unsigned n_smoother = profile_size() - + subpixel_smoother_width - + subpixel_center_width - + subpixel_scale*2; + + val = m_gamma[0]; + for(i = 0; i < n_smoother; i++) + { + *ch_smoother++ = (value_type)val; + } + + ch = ch_center; + for(i = 0; i < subpixel_scale*2; i++) + { + *--ch = *ch_center++; + } + } + + +} + diff --git a/src/agg_rounded_rect.cpp b/src/agg_rounded_rect.cpp new file mode 100644 index 0000000..1605091 --- /dev/null +++ b/src/agg_rounded_rect.cpp @@ -0,0 +1,164 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Rounded rectangle vertex generator +// +//---------------------------------------------------------------------------- + +#include <cmath> +#include "agg_rounded_rect.h" + + +namespace agg +{ + //------------------------------------------------------------------------ + rounded_rect::rounded_rect(double x1, double y1, double x2, double y2, double r) : + m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2), + m_rx1(r), m_ry1(r), m_rx2(r), m_ry2(r), + m_rx3(r), m_ry3(r), m_rx4(r), m_ry4(r) + { + if(x1 > x2) { m_x1 = x2; m_x2 = x1; } + if(y1 > y2) { m_y1 = y2; m_y2 = y1; } + } + + //-------------------------------------------------------------------- + void rounded_rect::rect(double x1, double y1, double x2, double y2) + { + m_x1 = x1; + m_y1 = y1; + m_x2 = x2; + m_y2 = y2; + if(x1 > x2) { m_x1 = x2; m_x2 = x1; } + if(y1 > y2) { m_y1 = y2; m_y2 = y1; } + } + + //-------------------------------------------------------------------- + void rounded_rect::radius(double r) + { + m_rx1 = m_ry1 = m_rx2 = m_ry2 = m_rx3 = m_ry3 = m_rx4 = m_ry4 = r; + } + + //-------------------------------------------------------------------- + void rounded_rect::radius(double rx, double ry) + { + m_rx1 = m_rx2 = m_rx3 = m_rx4 = rx; + m_ry1 = m_ry2 = m_ry3 = m_ry4 = ry; + } + + //-------------------------------------------------------------------- + void rounded_rect::radius(double rx_bottom, double ry_bottom, + double rx_top, double ry_top) + { + m_rx1 = m_rx2 = rx_bottom; + m_rx3 = m_rx4 = rx_top; + m_ry1 = m_ry2 = ry_bottom; + m_ry3 = m_ry4 = ry_top; + } + + //-------------------------------------------------------------------- + void rounded_rect::radius(double rx1, double ry1, double rx2, double ry2, + double rx3, double ry3, double rx4, double ry4) + { + m_rx1 = rx1; m_ry1 = ry1; m_rx2 = rx2; m_ry2 = ry2; + m_rx3 = rx3; m_ry3 = ry3; m_rx4 = rx4; m_ry4 = ry4; + } + + //-------------------------------------------------------------------- + void rounded_rect::normalize_radius() + { + double dx = std::fabs(m_y2 - m_y1); + double dy = std::fabs(m_x2 - m_x1); + + double k = 1.0; + double t; + t = dx / (m_rx1 + m_rx2); if(t < k) k = t; + t = dx / (m_rx3 + m_rx4); if(t < k) k = t; + t = dy / (m_ry1 + m_ry2); if(t < k) k = t; + t = dy / (m_ry3 + m_ry4); if(t < k) k = t; + + if(k < 1.0) + { + m_rx1 *= k; m_ry1 *= k; m_rx2 *= k; m_ry2 *= k; + m_rx3 *= k; m_ry3 *= k; m_rx4 *= k; m_ry4 *= k; + } + } + + //-------------------------------------------------------------------- + void rounded_rect::rewind(unsigned) + { + m_status = 0; + } + + //-------------------------------------------------------------------- + unsigned rounded_rect::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + switch(m_status) + { + case 0: + m_arc.init(m_x1 + m_rx1, m_y1 + m_ry1, m_rx1, m_ry1, + pi, pi+pi*0.5); + m_arc.rewind(0); + m_status++; + + case 1: + cmd = m_arc.vertex(x, y); + if(is_stop(cmd)) m_status++; + else return cmd; + + case 2: + m_arc.init(m_x2 - m_rx2, m_y1 + m_ry2, m_rx2, m_ry2, + pi+pi*0.5, 0.0); + m_arc.rewind(0); + m_status++; + + case 3: + cmd = m_arc.vertex(x, y); + if(is_stop(cmd)) m_status++; + else return path_cmd_line_to; + + case 4: + m_arc.init(m_x2 - m_rx3, m_y2 - m_ry3, m_rx3, m_ry3, + 0.0, pi*0.5); + m_arc.rewind(0); + m_status++; + + case 5: + cmd = m_arc.vertex(x, y); + if(is_stop(cmd)) m_status++; + else return path_cmd_line_to; + + case 6: + m_arc.init(m_x1 + m_rx4, m_y2 - m_ry4, m_rx4, m_ry4, + pi*0.5, pi); + m_arc.rewind(0); + m_status++; + + case 7: + cmd = m_arc.vertex(x, y); + if(is_stop(cmd)) m_status++; + else return path_cmd_line_to; + + case 8: + cmd = path_cmd_end_poly | path_flags_close | path_flags_ccw; + m_status++; + break; + } + return cmd; + } + + +} + diff --git a/src/agg_sqrt_tables.cpp b/src/agg_sqrt_tables.cpp new file mode 100644 index 0000000..19a1bd8 --- /dev/null +++ b/src/agg_sqrt_tables.cpp @@ -0,0 +1,115 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// static tables for fast integer sqrt +// +//---------------------------------------------------------------------------- + +#include "agg_basics.h" + +namespace agg +{ + int16u g_sqrt_table[1024] = //----------g_sqrt_table + { + 0, + 2048,2896,3547,4096,4579,5017,5418,5793,6144,6476,6792,7094,7384,7663,7932,8192,8444, + 8689,8927,9159,9385,9606,9822,10033,10240,10443,10642,10837,11029,11217,11403,11585, + 11765,11942,12116,12288,12457,12625,12790,12953,13114,13273,13430,13585,13738,13890, + 14040,14189,14336,14482,14626,14768,14910,15050,15188,15326,15462,15597,15731,15864, + 15995,16126,16255,16384,16512,16638,16764,16888,17012,17135,17257,17378,17498,17618, + 17736,17854,17971,18087,18203,18318,18432,18545,18658,18770,18882,18992,19102,19212, + 19321,19429,19537,19644,19750,19856,19961,20066,20170,20274,20377,20480,20582,20684, + 20785,20886,20986,21085,21185,21283,21382,21480,21577,21674,21771,21867,21962,22058, + 22153,22247,22341,22435,22528,22621,22713,22806,22897,22989,23080,23170,23261,23351, + 23440,23530,23619,23707,23796,23884,23971,24059,24146,24232,24319,24405,24491,24576, + 24661,24746,24831,24915,24999,25083,25166,25249,25332,25415,25497,25580,25661,25743, + 25824,25905,25986,26067,26147,26227,26307,26387,26466,26545,26624,26703,26781,26859, + 26937,27015,27092,27170,27247,27324,27400,27477,27553,27629,27705,27780,27856,27931, + 28006,28081,28155,28230,28304,28378,28452,28525,28599,28672,28745,28818,28891,28963, + 29035,29108,29180,29251,29323,29394,29466,29537,29608,29678,29749,29819,29890,29960, + 30030,30099,30169,30238,30308,30377,30446,30515,30583,30652,30720,30788,30856,30924, + 30992,31059,31127,31194,31261,31328,31395,31462,31529,31595,31661,31727,31794,31859, + 31925,31991,32056,32122,32187,32252,32317,32382,32446,32511,32575,32640,32704,32768, + 32832,32896,32959,33023,33086,33150,33213,33276,33339,33402,33465,33527,33590,33652, + 33714,33776,33839,33900,33962,34024,34086,34147,34208,34270,34331,34392,34453,34514, + 34574,34635,34695,34756,34816,34876,34936,34996,35056,35116,35176,35235,35295,35354, + 35413,35472,35531,35590,35649,35708,35767,35825,35884,35942,36001,36059,36117,36175, + 36233,36291,36348,36406,36464,36521,36578,36636,36693,36750,36807,36864,36921,36978, + 37034,37091,37147,37204,37260,37316,37372,37429,37485,37540,37596,37652,37708,37763, + 37819,37874,37929,37985,38040,38095,38150,38205,38260,38315,38369,38424,38478,38533, + 38587,38642,38696,38750,38804,38858,38912,38966,39020,39073,39127,39181,39234,39287, + 39341,39394,39447,39500,39553,39606,39659,39712,39765,39818,39870,39923,39975,40028, + 40080,40132,40185,40237,40289,40341,40393,40445,40497,40548,40600,40652,40703,40755, + 40806,40857,40909,40960,41011,41062,41113,41164,41215,41266,41317,41368,41418,41469, + 41519,41570,41620,41671,41721,41771,41821,41871,41922,41972,42021,42071,42121,42171, + 42221,42270,42320,42369,42419,42468,42518,42567,42616,42665,42714,42763,42813,42861, + 42910,42959,43008,43057,43105,43154,43203,43251,43300,43348,43396,43445,43493,43541, + 43589,43637,43685,43733,43781,43829,43877,43925,43972,44020,44068,44115,44163,44210, + 44258,44305,44352,44400,44447,44494,44541,44588,44635,44682,44729,44776,44823,44869, + 44916,44963,45009,45056,45103,45149,45195,45242,45288,45334,45381,45427,45473,45519, + 45565,45611,45657,45703,45749,45795,45840,45886,45932,45977,46023,46069,46114,46160, + 46205,46250,46296,46341,46386,46431,46477,46522,46567,46612,46657,46702,46746,46791, + 46836,46881,46926,46970,47015,47059,47104,47149,47193,47237,47282,47326,47370,47415, + 47459,47503,47547,47591,47635,47679,47723,47767,47811,47855,47899,47942,47986,48030, + 48074,48117,48161,48204,48248,48291,48335,48378,48421,48465,48508,48551,48594,48637, + 48680,48723,48766,48809,48852,48895,48938,48981,49024,49067,49109,49152,49195,49237, + 49280,49322,49365,49407,49450,49492,49535,49577,49619,49661,49704,49746,49788,49830, + 49872,49914,49956,49998,50040,50082,50124,50166,50207,50249,50291,50332,50374,50416, + 50457,50499,50540,50582,50623,50665,50706,50747,50789,50830,50871,50912,50954,50995, + 51036,51077,51118,51159,51200,51241,51282,51323,51364,51404,51445,51486,51527,51567, + 51608,51649,51689,51730,51770,51811,51851,51892,51932,51972,52013,52053,52093,52134, + 52174,52214,52254,52294,52334,52374,52414,52454,52494,52534,52574,52614,52654,52694, + 52734,52773,52813,52853,52892,52932,52972,53011,53051,53090,53130,53169,53209,53248, + 53287,53327,53366,53405,53445,53484,53523,53562,53601,53640,53679,53719,53758,53797, + 53836,53874,53913,53952,53991,54030,54069,54108,54146,54185,54224,54262,54301,54340, + 54378,54417,54455,54494,54532,54571,54609,54647,54686,54724,54762,54801,54839,54877, + 54915,54954,54992,55030,55068,55106,55144,55182,55220,55258,55296,55334,55372,55410, + 55447,55485,55523,55561,55599,55636,55674,55712,55749,55787,55824,55862,55900,55937, + 55975,56012,56049,56087,56124,56162,56199,56236,56273,56311,56348,56385,56422,56459, + 56497,56534,56571,56608,56645,56682,56719,56756,56793,56830,56867,56903,56940,56977, + 57014,57051,57087,57124,57161,57198,57234,57271,57307,57344,57381,57417,57454,57490, + 57527,57563,57599,57636,57672,57709,57745,57781,57817,57854,57890,57926,57962,57999, + 58035,58071,58107,58143,58179,58215,58251,58287,58323,58359,58395,58431,58467,58503, + 58538,58574,58610,58646,58682,58717,58753,58789,58824,58860,58896,58931,58967,59002, + 59038,59073,59109,59144,59180,59215,59251,59286,59321,59357,59392,59427,59463,59498, + 59533,59568,59603,59639,59674,59709,59744,59779,59814,59849,59884,59919,59954,59989, + 60024,60059,60094,60129,60164,60199,60233,60268,60303,60338,60373,60407,60442,60477, + 60511,60546,60581,60615,60650,60684,60719,60753,60788,60822,60857,60891,60926,60960, + 60995,61029,61063,61098,61132,61166,61201,61235,61269,61303,61338,61372,61406,61440, + 61474,61508,61542,61576,61610,61644,61678,61712,61746,61780,61814,61848,61882,61916, + 61950,61984,62018,62051,62085,62119,62153,62186,62220,62254,62287,62321,62355,62388, + 62422,62456,62489,62523,62556,62590,62623,62657,62690,62724,62757,62790,62824,62857, + 62891,62924,62957,62991,63024,63057,63090,63124,63157,63190,63223,63256,63289,63323, + 63356,63389,63422,63455,63488,63521,63554,63587,63620,63653,63686,63719,63752,63785, + 63817,63850,63883,63916,63949,63982,64014,64047,64080,64113,64145,64178,64211,64243, + 64276,64309,64341,64374,64406,64439,64471,64504,64536,64569,64601,64634,64666,64699, + 64731,64763,64796,64828,64861,64893,64925,64957,64990,65022,65054,65086,65119,65151, + 65183,65215,65247,65279,65312,65344,65376,65408,65440,65472,65504 + }; + + + int8 g_elder_bit_table[256] = //---------g_elder_bit_table + { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 + }; + +} diff --git a/src/agg_trans_affine.cpp b/src/agg_trans_affine.cpp new file mode 100644 index 0000000..961f8ee --- /dev/null +++ b/src/agg_trans_affine.cpp @@ -0,0 +1,194 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Affine transformations +// +//---------------------------------------------------------------------------- +#include "agg_trans_affine.h" + + + +namespace agg +{ + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::parl_to_parl(const double* src, + const double* dst) + { + sx = src[2] - src[0]; + shy = src[3] - src[1]; + shx = src[4] - src[0]; + sy = src[5] - src[1]; + tx = src[0]; + ty = src[1]; + invert(); + multiply(trans_affine(dst[2] - dst[0], dst[3] - dst[1], + dst[4] - dst[0], dst[5] - dst[1], + dst[0], dst[1])); + return *this; + } + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::rect_to_parl(double x1, double y1, + double x2, double y2, + const double* parl) + { + double src[6]; + src[0] = x1; src[1] = y1; + src[2] = x2; src[3] = y1; + src[4] = x2; src[5] = y2; + parl_to_parl(src, parl); + return *this; + } + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::parl_to_rect(const double* parl, + double x1, double y1, + double x2, double y2) + { + double dst[6]; + dst[0] = x1; dst[1] = y1; + dst[2] = x2; dst[3] = y1; + dst[4] = x2; dst[5] = y2; + parl_to_parl(parl, dst); + return *this; + } + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::multiply(const trans_affine& m) + { + double t0 = sx * m.sx + shy * m.shx; + double t2 = shx * m.sx + sy * m.shx; + double t4 = tx * m.sx + ty * m.shx + m.tx; + shy = sx * m.shy + shy * m.sy; + sy = shx * m.shy + sy * m.sy; + ty = tx * m.shy + ty * m.sy + m.ty; + sx = t0; + shx = t2; + tx = t4; + return *this; + } + + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::invert() + { + double d = determinant_reciprocal(); + + double t0 = sy * d; + sy = sx * d; + shy = -shy * d; + shx = -shx * d; + + double t4 = -tx * t0 - ty * shx; + ty = -tx * shy - ty * sy; + + sx = t0; + tx = t4; + return *this; + } + + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::flip_x() + { + sx = -sx; + shy = -shy; + tx = -tx; + return *this; + } + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::flip_y() + { + shx = -shx; + sy = -sy; + ty = -ty; + return *this; + } + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::reset() + { + sx = sy = 1.0; + shy = shx = tx = ty = 0.0; + return *this; + } + + //------------------------------------------------------------------------ + bool trans_affine::is_identity(double epsilon) const + { + return is_equal_eps(sx, 1.0, epsilon) && + is_equal_eps(shy, 0.0, epsilon) && + is_equal_eps(shx, 0.0, epsilon) && + is_equal_eps(sy, 1.0, epsilon) && + is_equal_eps(tx, 0.0, epsilon) && + is_equal_eps(ty, 0.0, epsilon); + } + + //------------------------------------------------------------------------ + bool trans_affine::is_valid(double epsilon) const + { + return std::fabs(sx) > epsilon && std::fabs(sy) > epsilon; + } + + //------------------------------------------------------------------------ + bool trans_affine::is_equal(const trans_affine& m, double epsilon) const + { + return is_equal_eps(sx, m.sx, epsilon) && + is_equal_eps(shy, m.shy, epsilon) && + is_equal_eps(shx, m.shx, epsilon) && + is_equal_eps(sy, m.sy, epsilon) && + is_equal_eps(tx, m.tx, epsilon) && + is_equal_eps(ty, m.ty, epsilon); + } + + //------------------------------------------------------------------------ + double trans_affine::rotation() const + { + double x1 = 0.0; + double y1 = 0.0; + double x2 = 1.0; + double y2 = 0.0; + transform(&x1, &y1); + transform(&x2, &y2); + return std::atan2(y2-y1, x2-x1); + } + + //------------------------------------------------------------------------ + void trans_affine::translation(double* dx, double* dy) const + { + *dx = tx; + *dy = ty; + } + + //------------------------------------------------------------------------ + void trans_affine::scaling(double* x, double* y) const + { + double x1 = 0.0; + double y1 = 0.0; + double x2 = 1.0; + double y2 = 1.0; + trans_affine t(*this); + t *= trans_affine_rotation(-rotation()); + t.transform(&x1, &y1); + t.transform(&x2, &y2); + *x = x2 - x1; + *y = y2 - y1; + } + + +} + diff --git a/src/agg_trans_double_path.cpp b/src/agg_trans_double_path.cpp new file mode 100644 index 0000000..cd40c7f --- /dev/null +++ b/src/agg_trans_double_path.cpp @@ -0,0 +1,273 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include "agg_math.h" +#include "agg_trans_double_path.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + trans_double_path::trans_double_path() : + m_kindex1(0.0), + m_kindex2(0.0), + m_base_length(0.0), + m_base_height(1.0), + m_status1(initial), + m_status2(initial), + m_preserve_x_scale(true) + { + } + + + //------------------------------------------------------------------------ + void trans_double_path::reset() + { + m_src_vertices1.remove_all(); + m_src_vertices2.remove_all(); + m_kindex1 = 0.0; + m_kindex1 = 0.0; + m_status1 = initial; + m_status2 = initial; + } + + + //------------------------------------------------------------------------ + void trans_double_path::move_to1(double x, double y) + { + if(m_status1 == initial) + { + m_src_vertices1.modify_last(vertex_dist(x, y)); + m_status1 = making_path; + } + else + { + line_to1(x, y); + } + } + + + //------------------------------------------------------------------------ + void trans_double_path::line_to1(double x, double y) + { + if(m_status1 == making_path) + { + m_src_vertices1.add(vertex_dist(x, y)); + } + } + + + //------------------------------------------------------------------------ + void trans_double_path::move_to2(double x, double y) + { + if(m_status2 == initial) + { + m_src_vertices2.modify_last(vertex_dist(x, y)); + m_status2 = making_path; + } + else + { + line_to2(x, y); + } + } + + + //------------------------------------------------------------------------ + void trans_double_path::line_to2(double x, double y) + { + if(m_status2 == making_path) + { + m_src_vertices2.add(vertex_dist(x, y)); + } + } + + + //------------------------------------------------------------------------ + double trans_double_path::finalize_path(vertex_storage& vertices) + { + unsigned i; + double dist; + double d; + + vertices.close(false); + if(vertices.size() > 2) + { + if(vertices[vertices.size() - 2].dist * 10.0 < + vertices[vertices.size() - 3].dist) + { + d = vertices[vertices.size() - 3].dist + + vertices[vertices.size() - 2].dist; + + vertices[vertices.size() - 2] = + vertices[vertices.size() - 1]; + + vertices.remove_last(); + vertices[vertices.size() - 2].dist = d; + } + } + + dist = 0; + for(i = 0; i < vertices.size(); i++) + { + vertex_dist& v = vertices[i]; + d = v.dist; + v.dist = dist; + dist += d; + } + + return (vertices.size() - 1) / dist; + } + + + //------------------------------------------------------------------------ + void trans_double_path::finalize_paths() + { + if(m_status1 == making_path && m_src_vertices1.size() > 1 && + m_status2 == making_path && m_src_vertices2.size() > 1) + { + m_kindex1 = finalize_path(m_src_vertices1); + m_kindex2 = finalize_path(m_src_vertices2); + m_status1 = ready; + m_status2 = ready; + } + } + + + //------------------------------------------------------------------------ + double trans_double_path::total_length1() const + { + if(m_base_length >= 1e-10) return m_base_length; + return (m_status1 == ready) ? + m_src_vertices1[m_src_vertices1.size() - 1].dist : + 0.0; + } + + + //------------------------------------------------------------------------ + double trans_double_path::total_length2() const + { + if(m_base_length >= 1e-10) return m_base_length; + return (m_status2 == ready) ? + m_src_vertices2[m_src_vertices2.size() - 1].dist : + 0.0; + } + + + //------------------------------------------------------------------------ + void trans_double_path::transform1(const vertex_storage& vertices, + double kindex, double kx, + double *x, double* y) const + { + double x1 = 0.0; + double y1 = 0.0; + double dx = 1.0; + double dy = 1.0; + double d = 0.0; + double dd = 1.0; + *x *= kx; + if(*x < 0.0) + { + // Extrapolation on the left + //-------------------------- + x1 = vertices[0].x; + y1 = vertices[0].y; + dx = vertices[1].x - x1; + dy = vertices[1].y - y1; + dd = vertices[1].dist - vertices[0].dist; + d = *x; + } + else + if(*x > vertices[vertices.size() - 1].dist) + { + // Extrapolation on the right + //-------------------------- + unsigned i = vertices.size() - 2; + unsigned j = vertices.size() - 1; + x1 = vertices[j].x; + y1 = vertices[j].y; + dx = x1 - vertices[i].x; + dy = y1 - vertices[i].y; + dd = vertices[j].dist - vertices[i].dist; + d = *x - vertices[j].dist; + } + else + { + // Interpolation + //-------------------------- + unsigned i = 0; + unsigned j = vertices.size() - 1; + if(m_preserve_x_scale) + { + unsigned k; + for(i = 0; (j - i) > 1; ) + { + if(*x < vertices[k = (i + j) >> 1].dist) + { + j = k; + } + else + { + i = k; + } + } + d = vertices[i].dist; + dd = vertices[j].dist - d; + d = *x - d; + } + else + { + i = unsigned(*x * kindex); + j = i + 1; + dd = vertices[j].dist - vertices[i].dist; + d = ((*x * kindex) - i) * dd; + } + x1 = vertices[i].x; + y1 = vertices[i].y; + dx = vertices[j].x - x1; + dy = vertices[j].y - y1; + } + *x = x1 + dx * d / dd; + *y = y1 + dy * d / dd; + } + + + //------------------------------------------------------------------------ + void trans_double_path::transform(double *x, double *y) const + { + if(m_status1 == ready && m_status2 == ready) + { + if(m_base_length > 1e-10) + { + *x *= m_src_vertices1[m_src_vertices1.size() - 1].dist / + m_base_length; + } + + double x1 = *x; + double y1 = *y; + double x2 = *x; + double y2 = *y; + double dd = m_src_vertices2[m_src_vertices2.size() - 1].dist / + m_src_vertices1[m_src_vertices1.size() - 1].dist; + + transform1(m_src_vertices1, m_kindex1, 1.0, &x1, &y1); + transform1(m_src_vertices2, m_kindex2, dd, &x2, &y2); + + *x = x1 + *y * (x2 - x1) / m_base_height; + *y = y1 + *y * (y2 - y1) / m_base_height; + } + } + +} + diff --git a/src/agg_trans_single_path.cpp b/src/agg_trans_single_path.cpp new file mode 100644 index 0000000..2120fc9 --- /dev/null +++ b/src/agg_trans_single_path.cpp @@ -0,0 +1,202 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include "agg_math.h" +#include "agg_vertex_sequence.h" +#include "agg_trans_single_path.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + trans_single_path::trans_single_path() : + m_base_length(0.0), + m_kindex(0.0), + m_status(initial), + m_preserve_x_scale(true) + { + } + + //------------------------------------------------------------------------ + void trans_single_path::reset() + { + m_src_vertices.remove_all(); + m_kindex = 0.0; + m_status = initial; + } + + //------------------------------------------------------------------------ + void trans_single_path::move_to(double x, double y) + { + if(m_status == initial) + { + m_src_vertices.modify_last(vertex_dist(x, y)); + m_status = making_path; + } + else + { + line_to(x, y); + } + } + + //------------------------------------------------------------------------ + void trans_single_path::line_to(double x, double y) + { + if(m_status == making_path) + { + m_src_vertices.add(vertex_dist(x, y)); + } + } + + + //------------------------------------------------------------------------ + void trans_single_path::finalize_path() + { + if(m_status == making_path && m_src_vertices.size() > 1) + { + unsigned i; + double dist; + double d; + + m_src_vertices.close(false); + if(m_src_vertices.size() > 2) + { + if(m_src_vertices[m_src_vertices.size() - 2].dist * 10.0 < + m_src_vertices[m_src_vertices.size() - 3].dist) + { + d = m_src_vertices[m_src_vertices.size() - 3].dist + + m_src_vertices[m_src_vertices.size() - 2].dist; + + m_src_vertices[m_src_vertices.size() - 2] = + m_src_vertices[m_src_vertices.size() - 1]; + + m_src_vertices.remove_last(); + m_src_vertices[m_src_vertices.size() - 2].dist = d; + } + } + + dist = 0.0; + for(i = 0; i < m_src_vertices.size(); i++) + { + vertex_dist& v = m_src_vertices[i]; + double d = v.dist; + v.dist = dist; + dist += d; + } + m_kindex = (m_src_vertices.size() - 1) / dist; + m_status = ready; + } + } + + + + //------------------------------------------------------------------------ + double trans_single_path::total_length() const + { + if(m_base_length >= 1e-10) return m_base_length; + return (m_status == ready) ? + m_src_vertices[m_src_vertices.size() - 1].dist : + 0.0; + } + + + //------------------------------------------------------------------------ + void trans_single_path::transform(double *x, double *y) const + { + if(m_status == ready) + { + if(m_base_length > 1e-10) + { + *x *= m_src_vertices[m_src_vertices.size() - 1].dist / + m_base_length; + } + + double x1 = 0.0; + double y1 = 0.0; + double dx = 1.0; + double dy = 1.0; + double d = 0.0; + double dd = 1.0; + if(*x < 0.0) + { + // Extrapolation on the left + //-------------------------- + x1 = m_src_vertices[0].x; + y1 = m_src_vertices[0].y; + dx = m_src_vertices[1].x - x1; + dy = m_src_vertices[1].y - y1; + dd = m_src_vertices[1].dist - m_src_vertices[0].dist; + d = *x; + } + else + if(*x > m_src_vertices[m_src_vertices.size() - 1].dist) + { + // Extrapolation on the right + //-------------------------- + unsigned i = m_src_vertices.size() - 2; + unsigned j = m_src_vertices.size() - 1; + x1 = m_src_vertices[j].x; + y1 = m_src_vertices[j].y; + dx = x1 - m_src_vertices[i].x; + dy = y1 - m_src_vertices[i].y; + dd = m_src_vertices[j].dist - m_src_vertices[i].dist; + d = *x - m_src_vertices[j].dist; + } + else + { + // Interpolation + //-------------------------- + unsigned i = 0; + unsigned j = m_src_vertices.size() - 1; + if(m_preserve_x_scale) + { + unsigned k; + for(i = 0; (j - i) > 1; ) + { + if(*x < m_src_vertices[k = (i + j) >> 1].dist) + { + j = k; + } + else + { + i = k; + } + } + d = m_src_vertices[i].dist; + dd = m_src_vertices[j].dist - d; + d = *x - d; + } + else + { + i = unsigned(*x * m_kindex); + j = i + 1; + dd = m_src_vertices[j].dist - m_src_vertices[i].dist; + d = ((*x * m_kindex) - i) * dd; + } + x1 = m_src_vertices[i].x; + y1 = m_src_vertices[i].y; + dx = m_src_vertices[j].x - x1; + dy = m_src_vertices[j].y - y1; + } + double x2 = x1 + dx * d / dd; + double y2 = y1 + dy * d / dd; + *x = x2 - *y * dy / dd; + *y = y2 + *y * dx / dd; + } + } + + +} + diff --git a/src/agg_trans_warp_magnifier.cpp b/src/agg_trans_warp_magnifier.cpp new file mode 100644 index 0000000..f4bfc5d --- /dev/null +++ b/src/agg_trans_warp_magnifier.cpp @@ -0,0 +1,70 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include <cmath> +#include "agg_trans_warp_magnifier.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + void trans_warp_magnifier::transform(double* x, double* y) const + { + double dx = *x - m_xc; + double dy = *y - m_yc; + double r = std::sqrt(dx * dx + dy * dy); + if(r < m_radius) + { + *x = m_xc + dx * m_magn; + *y = m_yc + dy * m_magn; + return; + } + + double m = (r + m_radius * (m_magn - 1.0)) / r; + *x = m_xc + dx * m; + *y = m_yc + dy * m; + } + + //------------------------------------------------------------------------ + void trans_warp_magnifier::inverse_transform(double* x, double* y) const + { + // New version by Andrew Skalkin + //----------------- + double dx = *x - m_xc; + double dy = *y - m_yc; + double r = std::sqrt(dx * dx + dy * dy); + + if(r < m_radius * m_magn) + { + *x = m_xc + dx / m_magn; + *y = m_yc + dy / m_magn; + } + else + { + double rnew = r - m_radius * (m_magn - 1.0); + *x = m_xc + rnew * dx / r; + *y = m_yc + rnew * dy / r; + } + + // Old version + //----------------- + //trans_warp_magnifier t(*this); + //t.magnification(1.0 / m_magn); + //t.radius(m_radius * m_magn); + //t.transform(x, y); + } + + +} diff --git a/src/agg_vcgen_bspline.cpp b/src/agg_vcgen_bspline.cpp new file mode 100644 index 0000000..4a0be66 --- /dev/null +++ b/src/agg_vcgen_bspline.cpp @@ -0,0 +1,194 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include "agg_vcgen_bspline.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + vcgen_bspline::vcgen_bspline() : + m_src_vertices(), + m_spline_x(), + m_spline_y(), + m_interpolation_step(1.0/50.0), + m_closed(0), + m_status(initial), + m_src_vertex(0) + { + } + + + //------------------------------------------------------------------------ + void vcgen_bspline::remove_all() + { + m_src_vertices.remove_all(); + m_closed = 0; + m_status = initial; + m_src_vertex = 0; + } + + + //------------------------------------------------------------------------ + void vcgen_bspline::add_vertex(double x, double y, unsigned cmd) + { + m_status = initial; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(point_d(x, y)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(point_d(x, y)); + } + else + { + m_closed = get_close_flag(cmd); + } + } + } + + + //------------------------------------------------------------------------ + void vcgen_bspline::rewind(unsigned) + { + m_cur_abscissa = 0.0; + m_max_abscissa = 0.0; + m_src_vertex = 0; + if(m_status == initial && m_src_vertices.size() > 2) + { + if(m_closed) + { + m_spline_x.init(m_src_vertices.size() + 8); + m_spline_y.init(m_src_vertices.size() + 8); + m_spline_x.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).x); + m_spline_y.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).y); + m_spline_x.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].x); + m_spline_y.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].y); + m_spline_x.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].x); + m_spline_y.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].y); + m_spline_x.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].x); + m_spline_y.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].y); + } + else + { + m_spline_x.init(m_src_vertices.size()); + m_spline_y.init(m_src_vertices.size()); + } + unsigned i; + for(i = 0; i < m_src_vertices.size(); i++) + { + double x = m_closed ? i + 4 : i; + m_spline_x.add_point(x, m_src_vertices[i].x); + m_spline_y.add_point(x, m_src_vertices[i].y); + } + m_cur_abscissa = 0.0; + m_max_abscissa = m_src_vertices.size() - 1; + if(m_closed) + { + m_cur_abscissa = 4.0; + m_max_abscissa += 5.0; + m_spline_x.add_point(m_src_vertices.size() + 4, m_src_vertices[0].x); + m_spline_y.add_point(m_src_vertices.size() + 4, m_src_vertices[0].y); + m_spline_x.add_point(m_src_vertices.size() + 5, m_src_vertices[1].x); + m_spline_y.add_point(m_src_vertices.size() + 5, m_src_vertices[1].y); + m_spline_x.add_point(m_src_vertices.size() + 6, m_src_vertices[2].x); + m_spline_y.add_point(m_src_vertices.size() + 6, m_src_vertices[2].y); + m_spline_x.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).x); + m_spline_y.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).y); + } + m_spline_x.prepare(); + m_spline_y.prepare(); + } + m_status = ready; + } + + + + + + + //------------------------------------------------------------------------ + unsigned vcgen_bspline::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + rewind(0); + + case ready: + if(m_src_vertices.size() < 2) + { + cmd = path_cmd_stop; + break; + } + + if(m_src_vertices.size() == 2) + { + *x = m_src_vertices[m_src_vertex].x; + *y = m_src_vertices[m_src_vertex].y; + m_src_vertex++; + if(m_src_vertex == 1) return path_cmd_move_to; + if(m_src_vertex == 2) return path_cmd_line_to; + cmd = path_cmd_stop; + break; + } + + cmd = path_cmd_move_to; + m_status = polygon; + m_src_vertex = 0; + + case polygon: + if(m_cur_abscissa >= m_max_abscissa) + { + if(m_closed) + { + m_status = end_poly; + break; + } + else + { + *x = m_src_vertices[m_src_vertices.size() - 1].x; + *y = m_src_vertices[m_src_vertices.size() - 1].y; + m_status = end_poly; + return path_cmd_line_to; + } + } + + *x = m_spline_x.get_stateful(m_cur_abscissa); + *y = m_spline_y.get_stateful(m_cur_abscissa); + m_src_vertex++; + m_cur_abscissa += m_interpolation_step; + return (m_src_vertex == 1) ? path_cmd_move_to : path_cmd_line_to; + + case end_poly: + m_status = stop; + return path_cmd_end_poly | m_closed; + + case stop: + return path_cmd_stop; + } + } + return cmd; + } + + +} + diff --git a/src/agg_vcgen_contour.cpp b/src/agg_vcgen_contour.cpp new file mode 100644 index 0000000..de8442f --- /dev/null +++ b/src/agg_vcgen_contour.cpp @@ -0,0 +1,164 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Contour generator +// +//---------------------------------------------------------------------------- + +#include "agg_vcgen_contour.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + vcgen_contour::vcgen_contour() : + m_stroker(), + m_width(1), + m_src_vertices(), + m_out_vertices(), + m_status(initial), + m_src_vertex(0), + m_closed(0), + m_orientation(0), + m_auto_detect(false) + { + } + + //------------------------------------------------------------------------ + void vcgen_contour::remove_all() + { + m_src_vertices.remove_all(); + m_closed = 0; + m_orientation = 0; + m_status = initial; + } + + //------------------------------------------------------------------------ + void vcgen_contour::add_vertex(double x, double y, unsigned cmd) + { + m_status = initial; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(vertex_dist(x, y)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(vertex_dist(x, y)); + } + else + { + if(is_end_poly(cmd)) + { + m_closed = get_close_flag(cmd); + if(m_orientation == path_flags_none) + { + m_orientation = get_orientation(cmd); + } + } + } + } + } + + //------------------------------------------------------------------------ + void vcgen_contour::rewind(unsigned) + { + if(m_status == initial) + { + m_src_vertices.close(true); + if(m_auto_detect) + { + if(!is_oriented(m_orientation)) + { + m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ? + path_flags_ccw : + path_flags_cw; + } + } + if(is_oriented(m_orientation)) + { + m_stroker.width(is_ccw(m_orientation) ? m_width : -m_width); + } + } + m_status = ready; + m_src_vertex = 0; + } + + //------------------------------------------------------------------------ + unsigned vcgen_contour::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + rewind(0); + + case ready: + if(m_src_vertices.size() < 2 + unsigned(m_closed != 0)) + { + cmd = path_cmd_stop; + break; + } + m_status = outline; + cmd = path_cmd_move_to; + m_src_vertex = 0; + m_out_vertex = 0; + + case outline: + if(m_src_vertex >= m_src_vertices.size()) + { + m_status = end_poly; + break; + } + m_stroker.calc_join(m_out_vertices, + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.next(m_src_vertex), + m_src_vertices.prev(m_src_vertex).dist, + m_src_vertices.curr(m_src_vertex).dist); + ++m_src_vertex; + m_status = out_vertices; + m_out_vertex = 0; + + case out_vertices: + if(m_out_vertex >= m_out_vertices.size()) + { + m_status = outline; + } + else + { + const point_d& c = m_out_vertices[m_out_vertex++]; + *x = c.x; + *y = c.y; + return cmd; + } + break; + + case end_poly: + if(!m_closed) return path_cmd_stop; + m_status = stop; + return path_cmd_end_poly | path_flags_close | path_flags_ccw; + + case stop: + return path_cmd_stop; + } + } + return cmd; + } + +} diff --git a/src/agg_vcgen_dash.cpp b/src/agg_vcgen_dash.cpp new file mode 100644 index 0000000..17cba78 --- /dev/null +++ b/src/agg_vcgen_dash.cpp @@ -0,0 +1,235 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Line dash generator +// +//---------------------------------------------------------------------------- + +#include <cmath> +#include "agg_vcgen_dash.h" +#include "agg_shorten_path.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + vcgen_dash::vcgen_dash() : + m_total_dash_len(0.0), + m_num_dashes(0), + m_dash_start(0.0), + m_shorten(0.0), + m_curr_dash_start(0.0), + m_curr_dash(0), + m_src_vertices(), + m_closed(0), + m_status(initial), + m_src_vertex(0) + { + } + + + + //------------------------------------------------------------------------ + void vcgen_dash::remove_all_dashes() + { + m_total_dash_len = 0.0; + m_num_dashes = 0; + m_curr_dash_start = 0.0; + m_curr_dash = 0; + } + + + //------------------------------------------------------------------------ + void vcgen_dash::add_dash(double dash_len, double gap_len) + { + if(m_num_dashes < max_dashes) + { + m_total_dash_len += dash_len + gap_len; + m_dashes[m_num_dashes++] = dash_len; + m_dashes[m_num_dashes++] = gap_len; + } + } + + + //------------------------------------------------------------------------ + void vcgen_dash::dash_start(double ds) + { + m_dash_start = ds; + calc_dash_start(std::fabs(ds)); + } + + + //------------------------------------------------------------------------ + void vcgen_dash::calc_dash_start(double ds) + { + m_curr_dash = 0; + m_curr_dash_start = 0.0; + while(ds > 0.0) + { + if(ds > m_dashes[m_curr_dash]) + { + ds -= m_dashes[m_curr_dash]; + ++m_curr_dash; + m_curr_dash_start = 0.0; + if(m_curr_dash >= m_num_dashes) m_curr_dash = 0; + } + else + { + m_curr_dash_start = ds; + ds = 0.0; + } + } + } + + + //------------------------------------------------------------------------ + void vcgen_dash::remove_all() + { + m_status = initial; + m_src_vertices.remove_all(); + m_closed = 0; + } + + + //------------------------------------------------------------------------ + void vcgen_dash::add_vertex(double x, double y, unsigned cmd) + { + m_status = initial; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(vertex_dist(x, y)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(vertex_dist(x, y)); + } + else + { + m_closed = get_close_flag(cmd); + } + } + } + + + //------------------------------------------------------------------------ + void vcgen_dash::rewind(unsigned) + { + if(m_status == initial) + { + m_src_vertices.close(m_closed != 0); + shorten_path(m_src_vertices, m_shorten, m_closed); + } + m_status = ready; + m_src_vertex = 0; + } + + + //------------------------------------------------------------------------ + unsigned vcgen_dash::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_move_to; + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + rewind(0); + + case ready: + if(m_num_dashes < 2 || m_src_vertices.size() < 2) + { + cmd = path_cmd_stop; + break; + } + m_status = polyline; + m_src_vertex = 1; + m_v1 = &m_src_vertices[0]; + m_v2 = &m_src_vertices[1]; + m_curr_rest = m_v1->dist; + *x = m_v1->x; + *y = m_v1->y; + if(m_dash_start >= 0.0) calc_dash_start(m_dash_start); + return path_cmd_move_to; + + case polyline: + { + double dash_rest = m_dashes[m_curr_dash] - m_curr_dash_start; + + unsigned cmd = (m_curr_dash & 1) ? + path_cmd_move_to : + path_cmd_line_to; + + if(m_curr_rest > dash_rest) + { + m_curr_rest -= dash_rest; + ++m_curr_dash; + if(m_curr_dash >= m_num_dashes) m_curr_dash = 0; + m_curr_dash_start = 0.0; + *x = m_v2->x - (m_v2->x - m_v1->x) * m_curr_rest / m_v1->dist; + *y = m_v2->y - (m_v2->y - m_v1->y) * m_curr_rest / m_v1->dist; + } + else + { + m_curr_dash_start += m_curr_rest; + *x = m_v2->x; + *y = m_v2->y; + ++m_src_vertex; + m_v1 = m_v2; + m_curr_rest = m_v1->dist; + if(m_closed) + { + if(m_src_vertex > m_src_vertices.size()) + { + m_status = stop; + } + else + { + m_v2 = &m_src_vertices + [ + (m_src_vertex >= m_src_vertices.size()) ? 0 : + m_src_vertex + ]; + } + } + else + { + if(m_src_vertex >= m_src_vertices.size()) + { + m_status = stop; + } + else + { + m_v2 = &m_src_vertices[m_src_vertex]; + } + } + } + return cmd; + } + break; + + case stop: + cmd = path_cmd_stop; + break; + } + + } + return path_cmd_stop; + } + + +} + diff --git a/src/agg_vcgen_markers_term.cpp b/src/agg_vcgen_markers_term.cpp new file mode 100644 index 0000000..3374ab5 --- /dev/null +++ b/src/agg_vcgen_markers_term.cpp @@ -0,0 +1,103 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Terminal markers generator (arrowhead/arrowtail) +// +//---------------------------------------------------------------------------- + +#include "agg_vcgen_markers_term.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + void vcgen_markers_term::remove_all() + { + m_markers.remove_all(); + } + + + //------------------------------------------------------------------------ + void vcgen_markers_term::add_vertex(double x, double y, unsigned cmd) + { + if(is_move_to(cmd)) + { + if(m_markers.size() & 1) + { + // Initial state, the first coordinate was added. + // If two of more calls of start_vertex() occures + // we just modify the last one. + m_markers.modify_last(coord_type(x, y)); + } + else + { + m_markers.add(coord_type(x, y)); + } + } + else + { + if(is_vertex(cmd)) + { + if(m_markers.size() & 1) + { + // Initial state, the first coordinate was added. + // Add three more points, 0,1,1,0 + m_markers.add(coord_type(x, y)); + m_markers.add(m_markers[m_markers.size() - 1]); + m_markers.add(m_markers[m_markers.size() - 3]); + } + else + { + if(m_markers.size()) + { + // Replace two last points: 0,1,1,0 -> 0,1,2,1 + m_markers[m_markers.size() - 1] = m_markers[m_markers.size() - 2]; + m_markers[m_markers.size() - 2] = coord_type(x, y); + } + } + } + } + } + + + //------------------------------------------------------------------------ + void vcgen_markers_term::rewind(unsigned path_id) + { + m_curr_id = path_id * 2; + m_curr_idx = m_curr_id; + } + + + //------------------------------------------------------------------------ + unsigned vcgen_markers_term::vertex(double* x, double* y) + { + if(m_curr_id > 2 || m_curr_idx >= m_markers.size()) + { + return path_cmd_stop; + } + const coord_type& c = m_markers[m_curr_idx]; + *x = c.x; + *y = c.y; + if(m_curr_idx & 1) + { + m_curr_idx += 3; + return path_cmd_line_to; + } + ++m_curr_idx; + return path_cmd_move_to; + } + + +} diff --git a/src/agg_vcgen_smooth_poly1.cpp b/src/agg_vcgen_smooth_poly1.cpp new file mode 100644 index 0000000..ff7d488 --- /dev/null +++ b/src/agg_vcgen_smooth_poly1.cpp @@ -0,0 +1,225 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Smooth polygon generator +// +//---------------------------------------------------------------------------- + +#include "agg_vcgen_smooth_poly1.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + vcgen_smooth_poly1::vcgen_smooth_poly1() : + m_src_vertices(), + m_smooth_value(0.5), + m_closed(0), + m_status(initial), + m_src_vertex(0) + { + } + + + //------------------------------------------------------------------------ + void vcgen_smooth_poly1::remove_all() + { + m_src_vertices.remove_all(); + m_closed = 0; + m_status = initial; + } + + + //------------------------------------------------------------------------ + void vcgen_smooth_poly1::add_vertex(double x, double y, unsigned cmd) + { + m_status = initial; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(vertex_dist(x, y)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(vertex_dist(x, y)); + } + else + { + m_closed = get_close_flag(cmd); + } + } + } + + + //------------------------------------------------------------------------ + void vcgen_smooth_poly1::rewind(unsigned) + { + if(m_status == initial) + { + m_src_vertices.close(m_closed != 0); + } + m_status = ready; + m_src_vertex = 0; + } + + + //------------------------------------------------------------------------ + void vcgen_smooth_poly1::calculate(const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + const vertex_dist& v3) + { + + double k1 = v0.dist / (v0.dist + v1.dist); + double k2 = v1.dist / (v1.dist + v2.dist); + + double xm1 = v0.x + (v2.x - v0.x) * k1; + double ym1 = v0.y + (v2.y - v0.y) * k1; + double xm2 = v1.x + (v3.x - v1.x) * k2; + double ym2 = v1.y + (v3.y - v1.y) * k2; + + m_ctrl1_x = v1.x + m_smooth_value * (v2.x - xm1); + m_ctrl1_y = v1.y + m_smooth_value * (v2.y - ym1); + m_ctrl2_x = v2.x + m_smooth_value * (v1.x - xm2); + m_ctrl2_y = v2.y + m_smooth_value * (v1.y - ym2); + } + + + //------------------------------------------------------------------------ + unsigned vcgen_smooth_poly1::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + rewind(0); + + case ready: + if(m_src_vertices.size() < 2) + { + cmd = path_cmd_stop; + break; + } + + if(m_src_vertices.size() == 2) + { + *x = m_src_vertices[m_src_vertex].x; + *y = m_src_vertices[m_src_vertex].y; + m_src_vertex++; + if(m_src_vertex == 1) return path_cmd_move_to; + if(m_src_vertex == 2) return path_cmd_line_to; + cmd = path_cmd_stop; + break; + } + + cmd = path_cmd_move_to; + m_status = polygon; + m_src_vertex = 0; + + case polygon: + if(m_closed) + { + if(m_src_vertex >= m_src_vertices.size()) + { + *x = m_src_vertices[0].x; + *y = m_src_vertices[0].y; + m_status = end_poly; + return path_cmd_curve4; + } + } + else + { + if(m_src_vertex >= m_src_vertices.size() - 1) + { + *x = m_src_vertices[m_src_vertices.size() - 1].x; + *y = m_src_vertices[m_src_vertices.size() - 1].y; + m_status = end_poly; + return path_cmd_curve3; + } + } + + calculate(m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.next(m_src_vertex), + m_src_vertices.next(m_src_vertex + 1)); + + *x = m_src_vertices[m_src_vertex].x; + *y = m_src_vertices[m_src_vertex].y; + m_src_vertex++; + + if(m_closed) + { + m_status = ctrl1; + return ((m_src_vertex == 1) ? + path_cmd_move_to : + path_cmd_curve4); + } + else + { + if(m_src_vertex == 1) + { + m_status = ctrl_b; + return path_cmd_move_to; + } + if(m_src_vertex >= m_src_vertices.size() - 1) + { + m_status = ctrl_e; + return path_cmd_curve3; + } + m_status = ctrl1; + return path_cmd_curve4; + } + break; + + case ctrl_b: + *x = m_ctrl2_x; + *y = m_ctrl2_y; + m_status = polygon; + return path_cmd_curve3; + + case ctrl_e: + *x = m_ctrl1_x; + *y = m_ctrl1_y; + m_status = polygon; + return path_cmd_curve3; + + case ctrl1: + *x = m_ctrl1_x; + *y = m_ctrl1_y; + m_status = ctrl2; + return path_cmd_curve4; + + case ctrl2: + *x = m_ctrl2_x; + *y = m_ctrl2_y; + m_status = polygon; + return path_cmd_curve4; + + case end_poly: + m_status = stop; + return path_cmd_end_poly | m_closed; + + case stop: + return path_cmd_stop; + } + } + return cmd; + } + +} + diff --git a/src/agg_vcgen_stroke.cpp b/src/agg_vcgen_stroke.cpp new file mode 100644 index 0000000..046ac8c --- /dev/null +++ b/src/agg_vcgen_stroke.cpp @@ -0,0 +1,212 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// Stroke generator +// +//---------------------------------------------------------------------------- +#include "agg_vcgen_stroke.h" +#include "agg_shorten_path.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + vcgen_stroke::vcgen_stroke() : + m_stroker(), + m_src_vertices(), + m_out_vertices(), + m_shorten(0.0), + m_closed(0), + m_status(initial), + m_src_vertex(0), + m_out_vertex(0) + { + } + + //------------------------------------------------------------------------ + void vcgen_stroke::remove_all() + { + m_src_vertices.remove_all(); + m_closed = 0; + m_status = initial; + } + + + //------------------------------------------------------------------------ + void vcgen_stroke::add_vertex(double x, double y, unsigned cmd) + { + m_status = initial; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(vertex_dist(x, y)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(vertex_dist(x, y)); + } + else + { + m_closed = get_close_flag(cmd); + } + } + } + + //------------------------------------------------------------------------ + void vcgen_stroke::rewind(unsigned) + { + if(m_status == initial) + { + m_src_vertices.close(m_closed != 0); + shorten_path(m_src_vertices, m_shorten, m_closed); + if(m_src_vertices.size() < 3) m_closed = 0; + } + m_status = ready; + m_src_vertex = 0; + m_out_vertex = 0; + } + + + //------------------------------------------------------------------------ + unsigned vcgen_stroke::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + rewind(0); + + case ready: + if(m_src_vertices.size() < 2 + unsigned(m_closed != 0)) + { + cmd = path_cmd_stop; + break; + } + m_status = m_closed ? outline1 : cap1; + cmd = path_cmd_move_to; + m_src_vertex = 0; + m_out_vertex = 0; + break; + + case cap1: + m_stroker.calc_cap(m_out_vertices, + m_src_vertices[0], + m_src_vertices[1], + m_src_vertices[0].dist); + m_src_vertex = 1; + m_prev_status = outline1; + m_status = out_vertices; + m_out_vertex = 0; + break; + + case cap2: + m_stroker.calc_cap(m_out_vertices, + m_src_vertices[m_src_vertices.size() - 1], + m_src_vertices[m_src_vertices.size() - 2], + m_src_vertices[m_src_vertices.size() - 2].dist); + m_prev_status = outline2; + m_status = out_vertices; + m_out_vertex = 0; + break; + + case outline1: + if(m_closed) + { + if(m_src_vertex >= m_src_vertices.size()) + { + m_prev_status = close_first; + m_status = end_poly1; + break; + } + } + else + { + if(m_src_vertex >= m_src_vertices.size() - 1) + { + m_status = cap2; + break; + } + } + m_stroker.calc_join(m_out_vertices, + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.next(m_src_vertex), + m_src_vertices.prev(m_src_vertex).dist, + m_src_vertices.curr(m_src_vertex).dist); + ++m_src_vertex; + m_prev_status = m_status; + m_status = out_vertices; + m_out_vertex = 0; + break; + + case close_first: + m_status = outline2; + cmd = path_cmd_move_to; + + case outline2: + if(m_src_vertex <= unsigned(m_closed == 0)) + { + m_status = end_poly2; + m_prev_status = stop; + break; + } + + --m_src_vertex; + m_stroker.calc_join(m_out_vertices, + m_src_vertices.next(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex).dist, + m_src_vertices.prev(m_src_vertex).dist); + + m_prev_status = m_status; + m_status = out_vertices; + m_out_vertex = 0; + break; + + case out_vertices: + if(m_out_vertex >= m_out_vertices.size()) + { + m_status = m_prev_status; + } + else + { + const point_d& c = m_out_vertices[m_out_vertex++]; + *x = c.x; + *y = c.y; + return cmd; + } + break; + + case end_poly1: + m_status = m_prev_status; + return path_cmd_end_poly | path_flags_close | path_flags_ccw; + + case end_poly2: + m_status = m_prev_status; + return path_cmd_end_poly | path_flags_close | path_flags_cw; + + case stop: + cmd = path_cmd_stop; + break; + } + } + return cmd; + } + +} diff --git a/src/agg_vpgen_clip_polygon.cpp b/src/agg_vpgen_clip_polygon.cpp new file mode 100644 index 0000000..4524526 --- /dev/null +++ b/src/agg_vpgen_clip_polygon.cpp @@ -0,0 +1,133 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include "agg_vpgen_clip_polygon.h" +#include "agg_clip_liang_barsky.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + // Determine the clipping code of the vertex according to the + // Cyrus-Beck line clipping algorithm + // + // | | + // 0110 | 0010 | 0011 + // | | + // -------+--------+-------- clip_box.y2 + // | | + // 0100 | 0000 | 0001 + // | | + // -------+--------+-------- clip_box.y1 + // | | + // 1100 | 1000 | 1001 + // | | + // clip_box.x1 clip_box.x2 + // + // + unsigned vpgen_clip_polygon::clipping_flags(double x, double y) + { + if(x < m_clip_box.x1) + { + if(y > m_clip_box.y2) return 6; + if(y < m_clip_box.y1) return 12; + return 4; + } + + if(x > m_clip_box.x2) + { + if(y > m_clip_box.y2) return 3; + if(y < m_clip_box.y1) return 9; + return 1; + } + + if(y > m_clip_box.y2) return 2; + if(y < m_clip_box.y1) return 8; + + return 0; + } + + //---------------------------------------------------------------------------- + void vpgen_clip_polygon::reset() + { + m_vertex = 0; + m_num_vertices = 0; + } + + //---------------------------------------------------------------------------- + void vpgen_clip_polygon::move_to(double x, double y) + { + m_vertex = 0; + m_num_vertices = 0; + m_clip_flags = clipping_flags(x, y); + if(m_clip_flags == 0) + { + m_x[0] = x; + m_y[0] = y; + m_num_vertices = 1; + } + m_x1 = x; + m_y1 = y; + m_cmd = path_cmd_move_to; + } + + + //---------------------------------------------------------------------------- + void vpgen_clip_polygon::line_to(double x, double y) + { + m_vertex = 0; + m_num_vertices = 0; + unsigned flags = clipping_flags(x, y); + + if(m_clip_flags == flags) + { + if(flags == 0) + { + m_x[0] = x; + m_y[0] = y; + m_num_vertices = 1; + } + } + else + { + m_num_vertices = clip_liang_barsky(m_x1, m_y1, + x, y, + m_clip_box, + m_x, m_y); + } + + m_clip_flags = flags; + m_x1 = x; + m_y1 = y; + } + + + //---------------------------------------------------------------------------- + unsigned vpgen_clip_polygon::vertex(double* x, double* y) + { + if(m_vertex < m_num_vertices) + { + *x = m_x[m_vertex]; + *y = m_y[m_vertex]; + ++m_vertex; + unsigned cmd = m_cmd; + m_cmd = path_cmd_line_to; + return cmd; + } + return path_cmd_stop; + } + + +} diff --git a/src/agg_vpgen_clip_polyline.cpp b/src/agg_vpgen_clip_polyline.cpp new file mode 100644 index 0000000..6840803 --- /dev/null +++ b/src/agg_vpgen_clip_polyline.cpp @@ -0,0 +1,77 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include "agg_vpgen_clip_polyline.h" +#include "agg_clip_liang_barsky.h" + +namespace agg +{ + //---------------------------------------------------------------------------- + void vpgen_clip_polyline::reset() + { + m_vertex = 0; + m_num_vertices = 0; + m_move_to = false; + } + + //---------------------------------------------------------------------------- + void vpgen_clip_polyline::move_to(double x, double y) + { + m_vertex = 0; + m_num_vertices = 0; + m_x1 = x; + m_y1 = y; + m_move_to = true; + } + + //---------------------------------------------------------------------------- + void vpgen_clip_polyline::line_to(double x, double y) + { + double x2 = x; + double y2 = y; + unsigned flags = clip_line_segment(&m_x1, &m_y1, &x2, &y2, m_clip_box); + + m_vertex = 0; + m_num_vertices = 0; + if((flags & 4) == 0) + { + if((flags & 1) != 0 || m_move_to) + { + m_x[0] = m_x1; + m_y[0] = m_y1; + m_cmd[0] = path_cmd_move_to; + m_num_vertices = 1; + } + m_x[m_num_vertices] = x2; + m_y[m_num_vertices] = y2; + m_cmd[m_num_vertices++] = path_cmd_line_to; + m_move_to = (flags & 2) != 0; + } + m_x1 = x; + m_y1 = y; + } + + //---------------------------------------------------------------------------- + unsigned vpgen_clip_polyline::vertex(double* x, double* y) + { + if(m_vertex < m_num_vertices) + { + *x = m_x[m_vertex]; + *y = m_y[m_vertex]; + return m_cmd[m_vertex++]; + } + return path_cmd_stop; + } +} diff --git a/src/agg_vpgen_segmentator.cpp b/src/agg_vpgen_segmentator.cpp new file mode 100644 index 0000000..0499415 --- /dev/null +++ b/src/agg_vpgen_segmentator.cpp @@ -0,0 +1,67 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- + +#include <cmath> +#include "agg_vpgen_segmentator.h" + +namespace agg +{ + + void vpgen_segmentator::move_to(double x, double y) + { + m_x1 = x; + m_y1 = y; + m_dx = 0.0; + m_dy = 0.0; + m_dl = 2.0; + m_ddl = 2.0; + m_cmd = path_cmd_move_to; + } + + void vpgen_segmentator::line_to(double x, double y) + { + m_x1 += m_dx; + m_y1 += m_dy; + m_dx = x - m_x1; + m_dy = y - m_y1; + double len = std::sqrt(m_dx * m_dx + m_dy * m_dy) * m_approximation_scale; + if(len < 1e-30) len = 1e-30; + m_ddl = 1.0 / len; + m_dl = (m_cmd == path_cmd_move_to) ? 0.0 : m_ddl; + if(m_cmd == path_cmd_stop) m_cmd = path_cmd_line_to; + } + + unsigned vpgen_segmentator::vertex(double* x, double* y) + { + if(m_cmd == path_cmd_stop) return path_cmd_stop; + + unsigned cmd = m_cmd; + m_cmd = path_cmd_line_to; + if(m_dl >= 1.0 - m_ddl) + { + m_dl = 1.0; + m_cmd = path_cmd_stop; + *x = m_x1 + m_dx; + *y = m_y1 + m_dy; + return cmd; + } + *x = m_x1 + m_dx * m_dl; + *y = m_y1 + m_dy * m_dl; + m_dl += m_ddl; + return cmd; + } + +} + diff --git a/src/ctrl/Makefile.am b/src/ctrl/Makefile.am new file mode 100644 index 0000000..c51aab6 --- /dev/null +++ b/src/ctrl/Makefile.am @@ -0,0 +1,11 @@ +if ENABLE_CTRL +INCLUDES = -I$(top_srcdir)/include + +noinst_LTLIBRARIES = libaggctrl.la + +libaggctrl_la_LDFLAGS = -no-undefined -version-info @AGG_LIB_VERSION@ +libaggctrl_la_SOURCES = agg_cbox_ctrl.cpp agg_gamma_ctrl.cpp agg_gamma_spline.cpp agg_rbox_ctrl.cpp \ + agg_slider_ctrl.cpp agg_spline_ctrl.cpp agg_scale_ctrl.cpp \ + agg_bezier_ctrl.cpp agg_polygon_ctrl.cpp + +endif diff --git a/src/ctrl/agg_bezier_ctrl.cpp b/src/ctrl/agg_bezier_ctrl.cpp new file mode 100644 index 0000000..4094134 --- /dev/null +++ b/src/ctrl/agg_bezier_ctrl.cpp @@ -0,0 +1,370 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes bezier_ctrl_impl, bezier_ctrl +// +//---------------------------------------------------------------------------- + +#include <string.h> +#include <stdio.h> +#include "ctrl/agg_bezier_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + bezier_ctrl_impl::bezier_ctrl_impl() : + ctrl(0,0,1,1,false), + m_stroke(m_curve), + m_poly(4, 5.0), + m_idx(0) + { + m_poly.in_polygon_check(false); + m_poly.xn(0) = 100.0; + m_poly.yn(0) = 0.0; + m_poly.xn(1) = 100.0; + m_poly.yn(1) = 50.0; + m_poly.xn(2) = 50.0; + m_poly.yn(2) = 100.0; + m_poly.xn(3) = 0.0; + m_poly.yn(3) = 100.0; + } + + + //------------------------------------------------------------------------ + void bezier_ctrl_impl::curve(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_poly.xn(0) = x1; + m_poly.yn(0) = y1; + m_poly.xn(1) = x2; + m_poly.yn(1) = y2; + m_poly.xn(2) = x3; + m_poly.yn(2) = y3; + m_poly.xn(3) = x4; + m_poly.yn(3) = y4; + curve(); + } + + //------------------------------------------------------------------------ + curve4& bezier_ctrl_impl::curve() + { + m_curve.init(m_poly.xn(0), m_poly.yn(0), + m_poly.xn(1), m_poly.yn(1), + m_poly.xn(2), m_poly.yn(2), + m_poly.xn(3), m_poly.yn(3)); + return m_curve; + } + + //------------------------------------------------------------------------ + void bezier_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + m_curve.approximation_scale(scale()); + switch(idx) + { + default: + case 0: // Control line 1 + m_curve.init(m_poly.xn(0), m_poly.yn(0), + (m_poly.xn(0) + m_poly.xn(1)) * 0.5, + (m_poly.yn(0) + m_poly.yn(1)) * 0.5, + (m_poly.xn(0) + m_poly.xn(1)) * 0.5, + (m_poly.yn(0) + m_poly.yn(1)) * 0.5, + m_poly.xn(1), m_poly.yn(1)); + m_stroke.rewind(0); + break; + + case 1: // Control line 2 + m_curve.init(m_poly.xn(2), m_poly.yn(2), + (m_poly.xn(2) + m_poly.xn(3)) * 0.5, + (m_poly.yn(2) + m_poly.yn(3)) * 0.5, + (m_poly.xn(2) + m_poly.xn(3)) * 0.5, + (m_poly.yn(2) + m_poly.yn(3)) * 0.5, + m_poly.xn(3), m_poly.yn(3)); + m_stroke.rewind(0); + break; + + case 2: // Curve itself + m_curve.init(m_poly.xn(0), m_poly.yn(0), + m_poly.xn(1), m_poly.yn(1), + m_poly.xn(2), m_poly.yn(2), + m_poly.xn(3), m_poly.yn(3)); + m_stroke.rewind(0); + break; + + case 3: // Point 1 + m_ellipse.init(m_poly.xn(0), m_poly.yn(0), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 4: // Point 2 + m_ellipse.init(m_poly.xn(1), m_poly.yn(1), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 5: // Point 3 + m_ellipse.init(m_poly.xn(2), m_poly.yn(2), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 6: // Point 4 + m_ellipse.init(m_poly.xn(3), m_poly.yn(3), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + } + } + + + //------------------------------------------------------------------------ + unsigned bezier_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + switch(m_idx) + { + case 0: + case 1: + case 2: + cmd = m_stroke.vertex(x, y); + break; + + case 3: + case 4: + case 5: + case 6: + case 7: + cmd = m_ellipse.vertex(x, y); + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + return cmd; + } + + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::in_rect(double, double) const + { + return false; + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + return m_poly.on_mouse_button_down(x, y); + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + return m_poly.on_mouse_move(x, y, button_flag); + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_mouse_button_up(double x, double y) + { + return m_poly.on_mouse_button_up(x, y); + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + return m_poly.on_arrow_keys(left, right, down, up); + } + + + + + + + //------------------------------------------------------------------------ + curve3_ctrl_impl::curve3_ctrl_impl() : + ctrl(0,0,1,1,false), + m_stroke(m_curve), + m_poly(3, 5.0), + m_idx(0) + { + m_poly.in_polygon_check(false); + m_poly.xn(0) = 100.0; + m_poly.yn(0) = 0.0; + m_poly.xn(1) = 100.0; + m_poly.yn(1) = 50.0; + m_poly.xn(2) = 50.0; + m_poly.yn(2) = 100.0; + } + + + //------------------------------------------------------------------------ + void curve3_ctrl_impl::curve(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + m_poly.xn(0) = x1; + m_poly.yn(0) = y1; + m_poly.xn(1) = x2; + m_poly.yn(1) = y2; + m_poly.xn(2) = x3; + m_poly.yn(2) = y3; + curve(); + } + + //------------------------------------------------------------------------ + curve3& curve3_ctrl_impl::curve() + { + m_curve.init(m_poly.xn(0), m_poly.yn(0), + m_poly.xn(1), m_poly.yn(1), + m_poly.xn(2), m_poly.yn(2)); + return m_curve; + } + + //------------------------------------------------------------------------ + void curve3_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + switch(idx) + { + default: + case 0: // Control line + m_curve.init(m_poly.xn(0), m_poly.yn(0), + (m_poly.xn(0) + m_poly.xn(1)) * 0.5, + (m_poly.yn(0) + m_poly.yn(1)) * 0.5, + m_poly.xn(1), m_poly.yn(1)); + m_stroke.rewind(0); + break; + + case 1: // Control line 2 + m_curve.init(m_poly.xn(1), m_poly.yn(1), + (m_poly.xn(1) + m_poly.xn(2)) * 0.5, + (m_poly.yn(1) + m_poly.yn(2)) * 0.5, + m_poly.xn(2), m_poly.yn(2)); + m_stroke.rewind(0); + break; + + case 2: // Curve itself + m_curve.init(m_poly.xn(0), m_poly.yn(0), + m_poly.xn(1), m_poly.yn(1), + m_poly.xn(2), m_poly.yn(2)); + m_stroke.rewind(0); + break; + + case 3: // Point 1 + m_ellipse.init(m_poly.xn(0), m_poly.yn(0), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 4: // Point 2 + m_ellipse.init(m_poly.xn(1), m_poly.yn(1), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 5: // Point 3 + m_ellipse.init(m_poly.xn(2), m_poly.yn(2), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + } + } + + + //------------------------------------------------------------------------ + unsigned curve3_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + switch(m_idx) + { + case 0: + case 1: + case 2: + cmd = m_stroke.vertex(x, y); + break; + + case 3: + case 4: + case 5: + case 6: + cmd = m_ellipse.vertex(x, y); + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + return cmd; + } + + + + //------------------------------------------------------------------------ + bool curve3_ctrl_impl::in_rect(double, double) const + { + return false; + } + + + //------------------------------------------------------------------------ + bool curve3_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + return m_poly.on_mouse_button_down(x, y); + } + + + //------------------------------------------------------------------------ + bool curve3_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + return m_poly.on_mouse_move(x, y, button_flag); + } + + + //------------------------------------------------------------------------ + bool curve3_ctrl_impl::on_mouse_button_up(double x, double y) + { + return m_poly.on_mouse_button_up(x, y); + } + + + //------------------------------------------------------------------------ + bool curve3_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + return m_poly.on_arrow_keys(left, right, down, up); + } + + + + + + + + + + + + +} + diff --git a/src/ctrl/agg_cbox_ctrl.cpp b/src/ctrl/agg_cbox_ctrl.cpp new file mode 100644 index 0000000..3cf14f6 --- /dev/null +++ b/src/ctrl/agg_cbox_ctrl.cpp @@ -0,0 +1,214 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes rbox_ctrl_impl, rbox_ctrl +// +//---------------------------------------------------------------------------- + +#include <string.h> +#include "ctrl/agg_cbox_ctrl.h" + + +namespace agg +{ + + //------------------------------------------------------------------------ + cbox_ctrl_impl::cbox_ctrl_impl(double x, double y, + const char* l, + bool flip_y) : + ctrl(x, y, x + 9.0 * 1.5, y + 9.0 * 1.5, flip_y), + m_text_thickness(1.5), + m_text_height(9.0), + m_text_width(0.0), + m_status(false), + m_text_poly(m_text) + { + label(l); + } + + + //------------------------------------------------------------------------ + void cbox_ctrl_impl::text_size(double h, double w) + { + m_text_width = w; + m_text_height = h; + } + + //------------------------------------------------------------------------ + void cbox_ctrl_impl::label(const char* l) + { + unsigned len = strlen(l); + if(len > 127) len = 127; + memcpy(m_label, l, len); + m_label[len] = 0; + } + + + //------------------------------------------------------------------------ + bool cbox_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + if(x >= m_x1 && y >= m_y1 && x <= m_x2 && y <= m_y2) + { + m_status = !m_status; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool cbox_ctrl_impl::on_mouse_move(double, double, bool) + { + return false; + } + + //------------------------------------------------------------------------ + bool cbox_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && y >= m_y1 && x <= m_x2 && y <= m_y2; + } + + //------------------------------------------------------------------------ + bool cbox_ctrl_impl::on_mouse_button_up(double, double) + { + return false; + } + + //------------------------------------------------------------------------ + bool cbox_ctrl_impl::on_arrow_keys(bool, bool, bool, bool) + { + return false; + } + + + //------------------------------------------------------------------------ + void cbox_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + double d2; + double t; + + switch(idx) + { + default: + case 0: // Border + m_vertex = 0; + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y2; + m_vx[4] = m_x1 + m_text_thickness; + m_vy[4] = m_y1 + m_text_thickness; + m_vx[5] = m_x1 + m_text_thickness; + m_vy[5] = m_y2 - m_text_thickness; + m_vx[6] = m_x2 - m_text_thickness; + m_vy[6] = m_y2 - m_text_thickness; + m_vx[7] = m_x2 - m_text_thickness; + m_vy[7] = m_y1 + m_text_thickness; + break; + + case 1: // Text + m_text.text(m_label); + m_text.start_point(m_x1 + m_text_height * 2.0, m_y1 + m_text_height / 5.0); + m_text.size(m_text_height, m_text_width); + m_text_poly.width(m_text_thickness); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); + m_text_poly.rewind(0); + break; + + case 2: // Active item + m_vertex = 0; + d2 = (m_y2 - m_y1) / 2.0; + t = m_text_thickness * 1.5; + m_vx[0] = m_x1 + m_text_thickness; + m_vy[0] = m_y1 + m_text_thickness; + m_vx[1] = m_x1 + d2; + m_vy[1] = m_y1 + d2 - t; + m_vx[2] = m_x2 - m_text_thickness; + m_vy[2] = m_y1 + m_text_thickness; + m_vx[3] = m_x1 + d2 + t; + m_vy[3] = m_y1 + d2; + m_vx[4] = m_x2 - m_text_thickness; + m_vy[4] = m_y2 - m_text_thickness; + m_vx[5] = m_x1 + d2; + m_vy[5] = m_y1 + d2 + t; + m_vx[6] = m_x1 + m_text_thickness; + m_vy[6] = m_y2 - m_text_thickness; + m_vx[7] = m_x1 + d2 - t; + m_vy[7] = m_y1 + d2; + break; + + } + } + + + + + //------------------------------------------------------------------------ + unsigned cbox_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; + if(m_vertex >= 8) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + cmd = m_text_poly.vertex(x, y); + break; + + case 2: + if(m_status) + { + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 8) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + } + else + { + cmd = path_cmd_stop; + } + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + return cmd; + } +} + + + diff --git a/src/ctrl/agg_gamma_ctrl.cpp b/src/ctrl/agg_gamma_ctrl.cpp new file mode 100644 index 0000000..7fd6448 --- /dev/null +++ b/src/ctrl/agg_gamma_ctrl.cpp @@ -0,0 +1,433 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class gamma_ctrl_impl +// +//---------------------------------------------------------------------------- + +#include <stdio.h> +#include "agg_math.h" +#include "ctrl/agg_gamma_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + gamma_ctrl_impl::gamma_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y) : + ctrl(x1, y1, x2, y2, flip_y), + m_border_width(2.0), + m_border_extra(0.0), + m_curve_width(2.0), + m_grid_width(0.2), + m_text_thickness(1.5), + m_point_size(5.0), + m_text_height(9.0), + m_text_width(0.0), + m_xc1(x1), + m_yc1(y1), + m_xc2(x2), + m_yc2(y2 - m_text_height * 2.0), + m_xt1(x1), + m_yt1(y2 - m_text_height * 2.0), + m_xt2(x2), + m_yt2(y2), + m_curve_poly(m_gamma_spline), + m_text_poly(m_text), + m_idx(0), + m_vertex(0), + m_p1_active(true), + m_mouse_point(0), + m_pdx(0.0), + m_pdy(0.0) + { + calc_spline_box(); + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::calc_spline_box() + { + m_xs1 = m_xc1 + m_border_width; + m_ys1 = m_yc1 + m_border_width; + m_xs2 = m_xc2 - m_border_width; + m_ys2 = m_yc2 - m_border_width * 0.5; + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::calc_points() + { + double kx1, ky1, kx2, ky2; + m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); + m_xp1 = m_xs1 + (m_xs2 - m_xs1) * kx1 * 0.25; + m_yp1 = m_ys1 + (m_ys2 - m_ys1) * ky1 * 0.25; + m_xp2 = m_xs2 - (m_xs2 - m_xs1) * kx2 * 0.25; + m_yp2 = m_ys2 - (m_ys2 - m_ys1) * ky2 * 0.25; + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::calc_values() + { + double kx1, ky1, kx2, ky2; + + kx1 = (m_xp1 - m_xs1) * 4.0 / (m_xs2 - m_xs1); + ky1 = (m_yp1 - m_ys1) * 4.0 / (m_ys2 - m_ys1); + kx2 = (m_xs2 - m_xp2) * 4.0 / (m_xs2 - m_xs1); + ky2 = (m_ys2 - m_yp2) * 4.0 / (m_ys2 - m_ys1); + m_gamma_spline.values(kx1, ky1, kx2, ky2); + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::text_size(double h, double w) + { + m_text_width = w; + m_text_height = h; + m_yc2 = m_y2 - m_text_height * 2.0; + m_yt1 = m_y2 - m_text_height * 2.0; + calc_spline_box(); + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::border_width(double t, double extra) + { + m_border_width = t; + m_border_extra = extra; + calc_spline_box(); + } + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::values(double kx1, double ky1, double kx2, double ky2) + { + m_gamma_spline.values(kx1, ky1, kx2, ky2); + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::values(double* kx1, double* ky1, double* kx2, double* ky2) const + { + m_gamma_spline.values(kx1, ky1, kx2, ky2); + } + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::rewind(unsigned idx) + { + double kx1, ky1, kx2, ky2; + char tbuf[32]; + + m_idx = idx; + + switch(idx) + { + default: + + case 0: // Background + m_vertex = 0; + m_vx[0] = m_x1 - m_border_extra; + m_vy[0] = m_y1 - m_border_extra; + m_vx[1] = m_x2 + m_border_extra; + m_vy[1] = m_y1 - m_border_extra; + m_vx[2] = m_x2 + m_border_extra; + m_vy[2] = m_y2 + m_border_extra; + m_vx[3] = m_x1 - m_border_extra; + m_vy[3] = m_y2 + m_border_extra; + break; + + case 1: // Border + m_vertex = 0; + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y2; + m_vx[4] = m_x1 + m_border_width; + m_vy[4] = m_y1 + m_border_width; + m_vx[5] = m_x1 + m_border_width; + m_vy[5] = m_y2 - m_border_width; + m_vx[6] = m_x2 - m_border_width; + m_vy[6] = m_y2 - m_border_width; + m_vx[7] = m_x2 - m_border_width; + m_vy[7] = m_y1 + m_border_width; + m_vx[8] = m_xc1 + m_border_width; + m_vy[8] = m_yc2 - m_border_width * 0.5; + m_vx[9] = m_xc2 - m_border_width; + m_vy[9] = m_yc2 - m_border_width * 0.5; + m_vx[10] = m_xc2 - m_border_width; + m_vy[10] = m_yc2 + m_border_width * 0.5; + m_vx[11] = m_xc1 + m_border_width; + m_vy[11] = m_yc2 + m_border_width * 0.5; + break; + + case 2: // Curve + m_gamma_spline.box(m_xs1, m_ys1, m_xs2, m_ys2); + m_curve_poly.width(m_curve_width); + m_curve_poly.rewind(0); + break; + + case 3: // Grid + m_vertex = 0; + m_vx[0] = m_xs1; + m_vy[0] = (m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5; + m_vx[1] = m_xs2; + m_vy[1] = (m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5; + m_vx[2] = m_xs2; + m_vy[2] = (m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5; + m_vx[3] = m_xs1; + m_vy[3] = (m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5; + m_vx[4] = (m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5; + m_vy[4] = m_ys1; + m_vx[5] = (m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5; + m_vy[5] = m_ys2; + m_vx[6] = (m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5; + m_vy[6] = m_ys2; + m_vx[7] = (m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5; + m_vy[7] = m_ys1; + calc_points(); + m_vx[8] = m_xs1; + m_vy[8] = m_yp1 - m_grid_width * 0.5; + m_vx[9] = m_xp1 - m_grid_width * 0.5; + m_vy[9] = m_yp1 - m_grid_width * 0.5; + m_vx[10] = m_xp1 - m_grid_width * 0.5; + m_vy[10] = m_ys1; + m_vx[11] = m_xp1 + m_grid_width * 0.5; + m_vy[11] = m_ys1; + m_vx[12] = m_xp1 + m_grid_width * 0.5; + m_vy[12] = m_yp1 + m_grid_width * 0.5; + m_vx[13] = m_xs1; + m_vy[13] = m_yp1 + m_grid_width * 0.5; + m_vx[14] = m_xs2; + m_vy[14] = m_yp2 + m_grid_width * 0.5; + m_vx[15] = m_xp2 + m_grid_width * 0.5; + m_vy[15] = m_yp2 + m_grid_width * 0.5; + m_vx[16] = m_xp2 + m_grid_width * 0.5; + m_vy[16] = m_ys2; + m_vx[17] = m_xp2 - m_grid_width * 0.5; + m_vy[17] = m_ys2; + m_vx[18] = m_xp2 - m_grid_width * 0.5; + m_vy[18] = m_yp2 - m_grid_width * 0.5; + m_vx[19] = m_xs2; + m_vy[19] = m_yp2 - m_grid_width * 0.5; + break; + + case 4: // Point1 + calc_points(); + if(m_p1_active) m_ellipse.init(m_xp2, m_yp2, m_point_size, m_point_size, 32); + else m_ellipse.init(m_xp1, m_yp1, m_point_size, m_point_size, 32); + break; + + case 5: // Point2 + calc_points(); + if(m_p1_active) m_ellipse.init(m_xp1, m_yp1, m_point_size, m_point_size, 32); + else m_ellipse.init(m_xp2, m_yp2, m_point_size, m_point_size, 32); + break; + + case 6: // Text + m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); + sprintf(tbuf, "%5.3f %5.3f %5.3f %5.3f", kx1, ky1, kx2, ky2); + m_text.text(tbuf); + m_text.size(m_text_height, m_text_width); + m_text.start_point(m_xt1 + m_border_width * 2.0, (m_yt1 + m_yt2) * 0.5 - m_text_height * 0.5); + m_text_poly.width(m_text_thickness); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); + m_text_poly.rewind(0); + break; + } + } + + + //------------------------------------------------------------------------ + unsigned gamma_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + if(m_vertex == 0 || m_vertex == 4 || m_vertex == 8) cmd = path_cmd_move_to; + if(m_vertex >= 12) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 2: + cmd = m_curve_poly.vertex(x, y); + break; + + case 3: + if(m_vertex == 0 || + m_vertex == 4 || + m_vertex == 8 || + m_vertex == 14) cmd = path_cmd_move_to; + + if(m_vertex >= 20) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 4: // Point1 + case 5: // Point2 + cmd = m_ellipse.vertex(x, y); + break; + + case 6: + cmd = m_text_poly.vertex(x, y); + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + + return cmd; + } + + + + //------------------------------------------------------------------------ + bool gamma_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + double kx1, ky1, kx2, ky2; + bool ret = false; + m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); + if(m_p1_active) + { + if(left) { kx1 -= 0.005; ret = true; } + if(right) { kx1 += 0.005; ret = true; } + if(down) { ky1 -= 0.005; ret = true; } + if(up) { ky1 += 0.005; ret = true; } + } + else + { + if(left) { kx2 += 0.005; ret = true; } + if(right) { kx2 -= 0.005; ret = true; } + if(down) { ky2 += 0.005; ret = true; } + if(up) { ky2 -= 0.005; ret = true; } + } + if(ret) + { + m_gamma_spline.values(kx1, ky1, kx2, ky2); + } + return ret; + } + + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::change_active_point() + { + m_p1_active = m_p1_active ? false : true; + } + + + + + //------------------------------------------------------------------------ + bool gamma_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; + } + + + //------------------------------------------------------------------------ + bool gamma_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + calc_points(); + + if(calc_distance(x, y, m_xp1, m_yp1) <= m_point_size + 1) + { + m_mouse_point = 1; + m_pdx = m_xp1 - x; + m_pdy = m_yp1 - y; + m_p1_active = true; + return true; + } + + if(calc_distance(x, y, m_xp2, m_yp2) <= m_point_size + 1) + { + m_mouse_point = 2; + m_pdx = m_xp2 - x; + m_pdy = m_yp2 - y; + m_p1_active = false; + return true; + } + + return false; + } + + + //------------------------------------------------------------------------ + bool gamma_ctrl_impl::on_mouse_button_up(double, double) + { + if(m_mouse_point) + { + m_mouse_point = 0; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool gamma_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + if(!button_flag) + { + return on_mouse_button_up(x, y); + } + + if(m_mouse_point == 1) + { + m_xp1 = x + m_pdx; + m_yp1 = y + m_pdy; + calc_values(); + return true; + } + if(m_mouse_point == 2) + { + m_xp2 = x + m_pdx; + m_yp2 = y + m_pdy; + calc_values(); + return true; + } + return false; + } + + + +} + diff --git a/src/ctrl/agg_gamma_spline.cpp b/src/ctrl/agg_gamma_spline.cpp new file mode 100644 index 0000000..f720fdd --- /dev/null +++ b/src/ctrl/agg_gamma_spline.cpp @@ -0,0 +1,130 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class gamma_spline +// +//---------------------------------------------------------------------------- + +#include "ctrl/agg_gamma_spline.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + gamma_spline::gamma_spline() : + m_x1(0), m_y1(0), m_x2(10), m_y2(10), m_cur_x(0.0) + { + values(1.0, 1.0, 1.0, 1.0); + } + + + //------------------------------------------------------------------------ + double gamma_spline::y(double x) const + { + if(x < 0.0) x = 0.0; + if(x > 1.0) x = 1.0; + double val = m_spline.get(x); + if(val < 0.0) val = 0.0; + if(val > 1.0) val = 1.0; + return val; + } + + + + //------------------------------------------------------------------------ + void gamma_spline::values(double kx1, double ky1, double kx2, double ky2) + { + if(kx1 < 0.001) kx1 = 0.001; + if(kx1 > 1.999) kx1 = 1.999; + if(ky1 < 0.001) ky1 = 0.001; + if(ky1 > 1.999) ky1 = 1.999; + if(kx2 < 0.001) kx2 = 0.001; + if(kx2 > 1.999) kx2 = 1.999; + if(ky2 < 0.001) ky2 = 0.001; + if(ky2 > 1.999) ky2 = 1.999; + + m_x[0] = 0.0; + m_y[0] = 0.0; + m_x[1] = kx1 * 0.25; + m_y[1] = ky1 * 0.25; + m_x[2] = 1.0 - kx2 * 0.25; + m_y[2] = 1.0 - ky2 * 0.25; + m_x[3] = 1.0; + m_y[3] = 1.0; + + m_spline.init(4, m_x, m_y); + + int i; + for(i = 0; i < 256; i++) + { + m_gamma[i] = (unsigned char)(y(double(i) / 255.0) * 255.0); + } + } + + + //------------------------------------------------------------------------ + void gamma_spline::values(double* kx1, double* ky1, double* kx2, double* ky2) const + { + *kx1 = m_x[1] * 4.0; + *ky1 = m_y[1] * 4.0; + *kx2 = (1.0 - m_x[2]) * 4.0; + *ky2 = (1.0 - m_y[2]) * 4.0; + } + + + //------------------------------------------------------------------------ + void gamma_spline::box(double x1, double y1, double x2, double y2) + { + m_x1 = x1; + m_y1 = y1; + m_x2 = x2; + m_y2 = y2; + } + + + //------------------------------------------------------------------------ + void gamma_spline::rewind(unsigned) + { + m_cur_x = 0.0; + } + + + //------------------------------------------------------------------------ + unsigned gamma_spline::vertex(double* vx, double* vy) + { + if(m_cur_x == 0.0) + { + *vx = m_x1; + *vy = m_y1; + m_cur_x += 1.0 / (m_x2 - m_x1); + return path_cmd_move_to; + } + + if(m_cur_x > 1.0) + { + return path_cmd_stop; + } + + *vx = m_x1 + m_cur_x * (m_x2 - m_x1); + *vy = m_y1 + y(m_cur_x) * (m_y2 - m_y1); + + m_cur_x += 1.0 / (m_x2 - m_x1); + return path_cmd_line_to; + } + + + +} + diff --git a/src/ctrl/agg_polygon_ctrl.cpp b/src/ctrl/agg_polygon_ctrl.cpp new file mode 100644 index 0000000..0d3eeca --- /dev/null +++ b/src/ctrl/agg_polygon_ctrl.cpp @@ -0,0 +1,332 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes polygon_ctrl_impl +// +//---------------------------------------------------------------------------- + +#include "ctrl/agg_polygon_ctrl.h" + +namespace agg +{ + + polygon_ctrl_impl::polygon_ctrl_impl(unsigned np, double point_radius) : + ctrl(0, 0, 1, 1, false), + 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_in_polygon_check(true) + { + m_stroke.width(1.0); + } + + + void polygon_ctrl_impl::rewind(unsigned) + { + m_status = 0; + m_stroke.rewind(0); + } + + unsigned polygon_ctrl_impl::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)) + { + transform_xy(x, y); + 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)) + { + transform_xy(x, y); + 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; + cmd = m_ellipse.vertex(x, y); + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + return cmd; + } + + + bool polygon_ctrl_impl::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 polygon_ctrl_impl::in_rect(double, double) const + { + return false; + } + + + bool polygon_ctrl_impl::on_mouse_button_down(double x, double y) + { + unsigned i; + bool ret = false; + m_node = -1; + m_edge = -1; + inverse_transform_xy(&x, &y); + 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 polygon_ctrl_impl::on_mouse_move(double x, double y, bool) + { + bool ret = false; + double dx; + double dy; + inverse_transform_xy(&x, &y); + 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 polygon_ctrl_impl::on_mouse_button_up(double, double) + { + bool ret = (m_node >= 0) || (m_edge >= 0); + m_node = -1; + m_edge = -1; + return ret; + } + + + bool polygon_ctrl_impl::on_arrow_keys(bool, bool, bool, bool) + { + return false; + } + + + //======= 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 polygon_ctrl_impl::point_in_polygon(double tx, double ty) const + { + if(m_num_points < 3) return false; + if(!m_in_polygon_check) 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; + } +} + diff --git a/src/ctrl/agg_rbox_ctrl.cpp b/src/ctrl/agg_rbox_ctrl.cpp new file mode 100644 index 0000000..4e36b3b --- /dev/null +++ b/src/ctrl/agg_rbox_ctrl.cpp @@ -0,0 +1,325 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes rbox_ctrl_impl, rbox_ctrl +// +//---------------------------------------------------------------------------- + +#include <string.h> +#include "ctrl/agg_rbox_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + rbox_ctrl_impl::rbox_ctrl_impl(double x1, double y1, + double x2, double y2, bool flip_y) : + ctrl(x1, y1, x2, y2, flip_y), + m_border_width(1.0), + m_border_extra(0.0), + m_text_thickness(1.5), + m_text_height(9.0), + m_text_width(0.0), + m_num_items(0), + m_cur_item(-1), + m_ellipse_poly(m_ellipse), + m_text_poly(m_text), + m_idx(0), + m_vertex(0) + { + calc_rbox(); + } + + + //------------------------------------------------------------------------ + void rbox_ctrl_impl::calc_rbox() + { + m_xs1 = m_x1 + m_border_width; + m_ys1 = m_y1 + m_border_width; + m_xs2 = m_x2 - m_border_width; + m_ys2 = m_y2 - m_border_width; + } + + + //------------------------------------------------------------------------ + void rbox_ctrl_impl::add_item(const char* text) + { + if(m_num_items < 32) + { + m_items[m_num_items].resize(strlen(text) + 1); + strcpy(&m_items[m_num_items][0], text); + m_num_items++; + } + } + + + //------------------------------------------------------------------------ + void rbox_ctrl_impl::border_width(double t, double extra) + { + m_border_width = t; + m_border_extra = extra; + calc_rbox(); + } + + + //------------------------------------------------------------------------ + void rbox_ctrl_impl::text_size(double h, double w) + { + m_text_width = w; + m_text_height = h; + } + + + + //------------------------------------------------------------------------ + void rbox_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + m_dy = m_text_height * 2.0; + m_draw_item = 0; + + switch(idx) + { + default: + + case 0: // Background + m_vertex = 0; + m_vx[0] = m_x1 - m_border_extra; + m_vy[0] = m_y1 - m_border_extra; + m_vx[1] = m_x2 + m_border_extra; + m_vy[1] = m_y1 - m_border_extra; + m_vx[2] = m_x2 + m_border_extra; + m_vy[2] = m_y2 + m_border_extra; + m_vx[3] = m_x1 - m_border_extra; + m_vy[3] = m_y2 + m_border_extra; + break; + + case 1: // Border + m_vertex = 0; + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y2; + m_vx[4] = m_x1 + m_border_width; + m_vy[4] = m_y1 + m_border_width; + m_vx[5] = m_x1 + m_border_width; + m_vy[5] = m_y2 - m_border_width; + m_vx[6] = m_x2 - m_border_width; + m_vy[6] = m_y2 - m_border_width; + m_vx[7] = m_x2 - m_border_width; + m_vy[7] = m_y1 + m_border_width; + break; + + case 2: // Text + m_text.text(&m_items[0][0]); + m_text.start_point(m_xs1 + m_dy * 1.5, m_ys1 + m_dy / 2.0); + m_text.size(m_text_height, m_text_width); + m_text_poly.width(m_text_thickness); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); + m_text_poly.rewind(0); + break; + + case 3: // Inactive items + m_ellipse.init(m_xs1 + m_dy / 1.3, + m_ys1 + m_dy / 1.3, + m_text_height / 1.5, + m_text_height / 1.5, 32); + m_ellipse_poly.width(m_text_thickness); + m_ellipse_poly.rewind(0); + break; + + + case 4: // Active Item + if(m_cur_item >= 0) + { + m_ellipse.init(m_xs1 + m_dy / 1.3, + m_ys1 + m_dy * m_cur_item + m_dy / 1.3, + m_text_height / 2.0, + m_text_height / 2.0, 32); + m_ellipse.rewind(0); + } + break; + + } + } + + + //------------------------------------------------------------------------ + unsigned rbox_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; + if(m_vertex >= 8) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 2: + cmd = m_text_poly.vertex(x, y); + if(is_stop(cmd)) + { + m_draw_item++; + if(m_draw_item >= m_num_items) + { + break; + } + else + { + m_text.text(&m_items[m_draw_item][0]); + m_text.start_point(m_xs1 + m_dy * 1.5, + m_ys1 + m_dy * (m_draw_item + 1) - m_dy / 2.0); + + m_text_poly.rewind(0); + cmd = m_text_poly.vertex(x, y); + } + } + break; + + case 3: + cmd = m_ellipse_poly.vertex(x, y); + if(is_stop(cmd)) + { + m_draw_item++; + if(m_draw_item >= m_num_items) + { + break; + } + else + { + m_ellipse.init(m_xs1 + m_dy / 1.3, + m_ys1 + m_dy * m_draw_item + m_dy / 1.3, + m_text_height / 1.5, + m_text_height / 1.5, 32); + m_ellipse_poly.rewind(0); + cmd = m_ellipse_poly.vertex(x, y); + } + } + break; + + + case 4: + if(m_cur_item >= 0) + { + cmd = m_ellipse.vertex(x, y); + } + else + { + cmd = path_cmd_stop; + } + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + + return cmd; + } + + + //------------------------------------------------------------------------ + bool rbox_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; + } + + + + //------------------------------------------------------------------------ + bool rbox_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + unsigned i; + for(i = 0; i < m_num_items; i++) + { + double xp = m_xs1 + m_dy / 1.3; + double yp = m_ys1 + m_dy * i + m_dy / 1.3; + if(calc_distance(x, y, xp, yp) <= m_text_height / 1.5) + { + m_cur_item = int(i); + return true; + } + } + return false; + } + + + //------------------------------------------------------------------------ + bool rbox_ctrl_impl::on_mouse_move(double, double, bool) + { + return false; + } + + //------------------------------------------------------------------------ + bool rbox_ctrl_impl::on_mouse_button_up(double, double) + { + return false; + } + + //------------------------------------------------------------------------ + bool rbox_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + if(m_cur_item >= 0) + { + if(up || right) + { + m_cur_item++; + if(m_cur_item >= int(m_num_items)) + { + m_cur_item = 0; + } + return true; + } + + if(down || left) + { + m_cur_item--; + if(m_cur_item < 0) + { + m_cur_item = m_num_items - 1; + } + return true; + } + } + return false; + } + + +} + + diff --git a/src/ctrl/agg_scale_ctrl.cpp b/src/ctrl/agg_scale_ctrl.cpp new file mode 100644 index 0000000..361382b --- /dev/null +++ b/src/ctrl/agg_scale_ctrl.cpp @@ -0,0 +1,454 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes scale_ctrl_impl, scale_ctrl +// +//---------------------------------------------------------------------------- + +#include "ctrl/agg_scale_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + scale_ctrl_impl::scale_ctrl_impl(double x1, double y1, + double x2, double y2, bool flip_y) : + ctrl(x1, y1, x2, y2, flip_y), + m_border_thickness(1.0), + m_border_extra((fabs(x2 - x1) > fabs(y2 - y1)) ? (y2 - y1) / 2 : (x2 - x1) / 2), + m_pdx(0.0), + m_pdy(0.0), + m_move_what(move_nothing), + m_value1(0.3), + m_value2(0.7), + m_min_d(0.01) + { + calc_box(); + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::calc_box() + { + m_xs1 = m_x1 + m_border_thickness; + m_ys1 = m_y1 + m_border_thickness; + m_xs2 = m_x2 - m_border_thickness; + m_ys2 = m_y2 - m_border_thickness; + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::border_thickness(double t, double extra) + { + m_border_thickness = t; + m_border_extra = extra; + calc_box(); + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::resize(double x1, double y1, double x2, double y2) + { + m_x1 = x1; + m_y1 = y1; + m_x2 = x2; + m_y2 = y2; + calc_box(); + m_border_extra = (fabs(x2 - x1) > fabs(y2 - y1)) ? + (y2 - y1) / 2 : + (x2 - x1) / 2; + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::value1(double value) + { + if(value < 0.0) value = 0.0; + if(value > 1.0) value = 1.0; + if(m_value2 - value < m_min_d) value = m_value2 - m_min_d; + m_value1 = value; + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::value2(double value) + { + if(value < 0.0) value = 0.0; + if(value > 1.0) value = 1.0; + if(m_value1 + value < m_min_d) value = m_value1 + m_min_d; + m_value2 = value; + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::move(double d) + { + m_value1 += d; + m_value2 += d; + if(m_value1 < 0.0) + { + m_value2 -= m_value1; + m_value1 = 0.0; + } + if(m_value2 > 1.0) + { + m_value1 -= m_value2 - 1.0; + m_value2 = 1.0; + } + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + switch(idx) + { + default: + + case 0: // Background + m_vertex = 0; + m_vx[0] = m_x1 - m_border_extra; + m_vy[0] = m_y1 - m_border_extra; + m_vx[1] = m_x2 + m_border_extra; + m_vy[1] = m_y1 - m_border_extra; + m_vx[2] = m_x2 + m_border_extra; + m_vy[2] = m_y2 + m_border_extra; + m_vx[3] = m_x1 - m_border_extra; + m_vy[3] = m_y2 + m_border_extra; + break; + + case 1: // Border + m_vertex = 0; + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y2; + m_vx[4] = m_x1 + m_border_thickness; + m_vy[4] = m_y1 + m_border_thickness; + m_vx[5] = m_x1 + m_border_thickness; + m_vy[5] = m_y2 - m_border_thickness; + m_vx[6] = m_x2 - m_border_thickness; + m_vy[6] = m_y2 - m_border_thickness; + m_vx[7] = m_x2 - m_border_thickness; + m_vy[7] = m_y1 + m_border_thickness; + break; + + case 2: // pointer1 + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value1, + (m_ys1 + m_ys2) / 2.0, + m_y2 - m_y1, + m_y2 - m_y1, + 32); + } + else + { + m_ellipse.init((m_xs1 + m_xs2) / 2.0, + m_ys1 + (m_ys2 - m_ys1) * m_value1, + m_x2 - m_x1, + m_x2 - m_x1, + 32); + } + m_ellipse.rewind(0); + break; + + case 3: // pointer2 + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value2, + (m_ys1 + m_ys2) / 2.0, + m_y2 - m_y1, + m_y2 - m_y1, + 32); + } + else + { + m_ellipse.init((m_xs1 + m_xs2) / 2.0, + m_ys1 + (m_ys2 - m_ys1) * m_value2, + m_x2 - m_x1, + m_x2 - m_x1, + 32); + } + m_ellipse.rewind(0); + break; + + case 4: // slider + m_vertex = 0; + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_vx[0] = m_xs1 + (m_xs2 - m_xs1) * m_value1; + m_vy[0] = m_y1 - m_border_extra / 2.0; + m_vx[1] = m_xs1 + (m_xs2 - m_xs1) * m_value2; + m_vy[1] = m_vy[0]; + m_vx[2] = m_vx[1]; + m_vy[2] = m_y2 + m_border_extra / 2.0; + m_vx[3] = m_vx[0]; + m_vy[3] = m_vy[2]; + } + else + { + m_vx[0] = m_x1 - m_border_extra / 2.0; + m_vy[0] = m_ys1 + (m_ys2 - m_ys1) * m_value1; + m_vx[1] = m_vx[0]; + m_vy[1] = m_ys1 + (m_ys2 - m_ys1) * m_value2; + m_vx[2] = m_x2 + m_border_extra / 2.0; + m_vy[2] = m_vy[1]; + m_vx[3] = m_vx[2]; + m_vy[3] = m_vy[0]; + } + break; + } + } + + + //------------------------------------------------------------------------ + unsigned scale_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + case 4: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; + if(m_vertex >= 8) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 2: + case 3: + cmd = m_ellipse.vertex(x, y); + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + + return cmd; + } + + + + //------------------------------------------------------------------------ + bool scale_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; + } + + + //------------------------------------------------------------------------ + bool scale_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + + double xp1; + double xp2; + double ys1; + double ys2; + double xp; + double yp; + + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + xp1 = m_xs1 + (m_xs2 - m_xs1) * m_value1; + xp2 = m_xs1 + (m_xs2 - m_xs1) * m_value2; + ys1 = m_y1 - m_border_extra / 2.0; + ys2 = m_y2 + m_border_extra / 2.0; + yp = (m_ys1 + m_ys2) / 2.0; + + if(x > xp1 && y > ys1 && x < xp2 && y < ys2) + { + m_pdx = xp1 - x; + m_move_what = move_slider; + return true; + } + + //if(x < xp1 && calc_distance(x, y, xp1, yp) <= m_y2 - m_y1) + if(calc_distance(x, y, xp1, yp) <= m_y2 - m_y1) + { + m_pdx = xp1 - x; + m_move_what = move_value1; + return true; + } + + //if(x > xp2 && calc_distance(x, y, xp2, yp) <= m_y2 - m_y1) + if(calc_distance(x, y, xp2, yp) <= m_y2 - m_y1) + { + m_pdx = xp2 - x; + m_move_what = move_value2; + return true; + } + } + else + { + xp1 = m_x1 - m_border_extra / 2.0; + xp2 = m_x2 + m_border_extra / 2.0; + ys1 = m_ys1 + (m_ys2 - m_ys1) * m_value1; + ys2 = m_ys1 + (m_ys2 - m_ys1) * m_value2; + xp = (m_xs1 + m_xs2) / 2.0; + + if(x > xp1 && y > ys1 && x < xp2 && y < ys2) + { + m_pdy = ys1 - y; + m_move_what = move_slider; + return true; + } + + //if(y < ys1 && calc_distance(x, y, xp, ys1) <= m_x2 - m_x1) + if(calc_distance(x, y, xp, ys1) <= m_x2 - m_x1) + { + m_pdy = ys1 - y; + m_move_what = move_value1; + return true; + } + + //if(y > ys2 && calc_distance(x, y, xp, ys2) <= m_x2 - m_x1) + if(calc_distance(x, y, xp, ys2) <= m_x2 - m_x1) + { + m_pdy = ys2 - y; + m_move_what = move_value2; + return true; + } + } + + return false; + } + + + //------------------------------------------------------------------------ + bool scale_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + if(!button_flag) + { + return on_mouse_button_up(x, y); + } + + double xp = x + m_pdx; + double yp = y + m_pdy; + double dv; + + switch(m_move_what) + { + case move_value1: + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1); + } + else + { + m_value1 = (yp - m_ys1) / (m_ys2 - m_ys1); + } + if(m_value1 < 0.0) m_value1 = 0.0; + if(m_value1 > m_value2 - m_min_d) m_value1 = m_value2 - m_min_d; + return true; + + case move_value2: + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_value2 = (xp - m_xs1) / (m_xs2 - m_xs1); + } + else + { + m_value2 = (yp - m_ys1) / (m_ys2 - m_ys1); + } + if(m_value2 > 1.0) m_value2 = 1.0; + if(m_value2 < m_value1 + m_min_d) m_value2 = m_value1 + m_min_d; + return true; + + case move_slider: + dv = m_value2 - m_value1; + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1); + } + else + { + m_value1 = (yp - m_ys1) / (m_ys2 - m_ys1); + } + m_value2 = m_value1 + dv; + if(m_value1 < 0.0) + { + dv = m_value2 - m_value1; + m_value1 = 0.0; + m_value2 = m_value1 + dv; + } + if(m_value2 > 1.0) + { + dv = m_value2 - m_value1; + m_value2 = 1.0; + m_value1 = m_value2 - dv; + } + return true; + default: + return false; + } + } + + + //------------------------------------------------------------------------ + bool scale_ctrl_impl::on_mouse_button_up(double, double) + { + m_move_what = move_nothing; + return false; + } + + + //------------------------------------------------------------------------ + bool scale_ctrl_impl::on_arrow_keys(bool /*left*/, bool /*right*/, bool /*down*/, bool /*up*/) + { +/* + if(right || up) + { + m_value += 0.005; + if(m_value > 1.0) m_value = 1.0; + return true; + } + + if(left || down) + { + m_value -= 0.005; + if(m_value < 0.0) m_value = 0.0; + return true; + } +*/ + return false; + } + +} + diff --git a/src/ctrl/agg_slider_ctrl.cpp b/src/ctrl/agg_slider_ctrl.cpp new file mode 100644 index 0000000..ad00486 --- /dev/null +++ b/src/ctrl/agg_slider_ctrl.cpp @@ -0,0 +1,349 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes slider_ctrl_impl, slider_ctrl +// +//---------------------------------------------------------------------------- + +#include <string.h> +#include <stdio.h> +#include "ctrl/agg_slider_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + slider_ctrl_impl::slider_ctrl_impl(double x1, double y1, + double x2, double y2, bool flip_y) : + ctrl(x1, y1, x2, y2, flip_y), + m_border_width(1.0), + m_border_extra((y2 - y1) / 2), + m_text_thickness(1.0), + m_pdx(0.0), + m_mouse_move(false), + m_value(0.5), + m_preview_value(0.5), + m_min(0.0), + m_max(1.0), + m_num_steps(0), + m_descending(false), + m_text_poly(m_text) + { + m_label[0] = 0; + calc_box(); + } + + + //------------------------------------------------------------------------ + void slider_ctrl_impl::calc_box() + { + m_xs1 = m_x1 + m_border_width; + m_ys1 = m_y1 + m_border_width; + m_xs2 = m_x2 - m_border_width; + m_ys2 = m_y2 - m_border_width; + } + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::normalize_value(bool preview_value_flag) + { + bool ret = true; + if(m_num_steps) + { + int step = int(m_preview_value * m_num_steps + 0.5); + ret = m_value != step / double(m_num_steps); + m_value = step / double(m_num_steps); + } + else + { + m_value = m_preview_value; + } + + if(preview_value_flag) + { + m_preview_value = m_value; + } + return ret; + } + + + //------------------------------------------------------------------------ + void slider_ctrl_impl::border_width(double t, double extra) + { + m_border_width = t; + m_border_extra = extra; + calc_box(); + } + + + //------------------------------------------------------------------------ + void slider_ctrl_impl::value(double value) + { + m_preview_value = (value - m_min) / (m_max - m_min); + if(m_preview_value > 1.0) m_preview_value = 1.0; + if(m_preview_value < 0.0) m_preview_value = 0.0; + normalize_value(true); + } + + //------------------------------------------------------------------------ + void slider_ctrl_impl::label(const char* fmt) + { + m_label[0] = 0; + if(fmt) + { + unsigned len = strlen(fmt); + if(len > 63) len = 63; + memcpy(m_label, fmt, len); + m_label[len] = 0; + } + } + + //------------------------------------------------------------------------ + void slider_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + switch(idx) + { + default: + + case 0: // Background + m_vertex = 0; + m_vx[0] = m_x1 - m_border_extra; + m_vy[0] = m_y1 - m_border_extra; + m_vx[1] = m_x2 + m_border_extra; + m_vy[1] = m_y1 - m_border_extra; + m_vx[2] = m_x2 + m_border_extra; + m_vy[2] = m_y2 + m_border_extra; + m_vx[3] = m_x1 - m_border_extra; + m_vy[3] = m_y2 + m_border_extra; + break; + + case 1: // Triangle + m_vertex = 0; + if(m_descending) + { + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x1; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y1; + } + else + { + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y1; + } + break; + + case 2: + m_text.text(m_label); + if(m_label[0]) + { + char buf[256]; + sprintf(buf, m_label, value()); + m_text.text(buf); + } + m_text.start_point(m_x1, m_y1); + m_text.size((m_y2 - m_y1) * 1.2, m_y2 - m_y1); + m_text_poly.width(m_text_thickness); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); + m_text_poly.rewind(0); + break; + + case 3: // pointer preview + m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_preview_value, + (m_ys1 + m_ys2) / 2.0, + m_y2 - m_y1, + m_y2 - m_y1, + 32); + break; + + + case 4: // pointer + normalize_value(false); + m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value, + (m_ys1 + m_ys2) / 2.0, + m_y2 - m_y1, + m_y2 - m_y1, + 32); + m_ellipse.rewind(0); + break; + + case 5: + m_storage.remove_all(); + if(m_num_steps) + { + unsigned i; + double d = (m_xs2 - m_xs1) / m_num_steps; + if(d > 0.004) d = 0.004; + for(i = 0; i < m_num_steps + 1; i++) + { + double x = m_xs1 + (m_xs2 - m_xs1) * i / m_num_steps; + m_storage.move_to(x, m_y1); + m_storage.line_to(x - d * (m_x2 - m_x1), m_y1 - m_border_extra); + m_storage.line_to(x + d * (m_x2 - m_x1), m_y1 - m_border_extra); + } + } + } + } + + + //------------------------------------------------------------------------ + unsigned slider_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 2: + cmd = m_text_poly.vertex(x, y); + break; + + case 3: + case 4: + cmd = m_ellipse.vertex(x, y); + break; + + case 5: + cmd = m_storage.vertex(x, y); + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + + return cmd; + } + + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; + } + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + + double xp = m_xs1 + (m_xs2 - m_xs1) * m_value; + double yp = (m_ys1 + m_ys2) / 2.0; + + if(calc_distance(x, y, xp, yp) <= m_y2 - m_y1) + { + m_pdx = xp - x; + m_mouse_move = true; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + if(!button_flag) + { + on_mouse_button_up(x, y); + return false; + } + + if(m_mouse_move) + { + double xp = x + m_pdx; + m_preview_value = (xp - m_xs1) / (m_xs2 - m_xs1); + if(m_preview_value < 0.0) m_preview_value = 0.0; + if(m_preview_value > 1.0) m_preview_value = 1.0; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::on_mouse_button_up(double, double) + { + m_mouse_move = false; + normalize_value(true); + return true; + } + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + double d = 0.005; + if(m_num_steps) + { + d = 1.0 / m_num_steps; + } + + if(right || up) + { + m_preview_value += d; + if(m_preview_value > 1.0) m_preview_value = 1.0; + normalize_value(true); + return true; + } + + if(left || down) + { + m_preview_value -= d; + if(m_preview_value < 0.0) m_preview_value = 0.0; + normalize_value(true); + return true; + } + return false; + } + +} + diff --git a/src/ctrl/agg_spline_ctrl.cpp b/src/ctrl/agg_spline_ctrl.cpp new file mode 100644 index 0000000..74808d4 --- /dev/null +++ b/src/ctrl/agg_spline_ctrl.cpp @@ -0,0 +1,407 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// classes spline_ctrl_impl, spline_ctrl +// +//---------------------------------------------------------------------------- + +#include "ctrl/agg_spline_ctrl.h" + + +namespace agg +{ + + //------------------------------------------------------------------------ + spline_ctrl_impl::spline_ctrl_impl(double x1, double y1, double x2, double y2, + unsigned num_pnt, bool flip_y) : + ctrl(x1, y1, x2, y2, flip_y), + m_num_pnt(num_pnt), + m_border_width(1.0), + m_border_extra(0.0), + m_curve_width(1.0), + m_point_size(3.0), + m_curve_poly(m_curve_pnt), + m_idx(0), + m_vertex(0), + m_active_pnt(-1), + m_move_pnt(-1), + m_pdx(0.0), + m_pdy(0.0) + { + if(m_num_pnt < 4) m_num_pnt = 4; + if(m_num_pnt > 32) m_num_pnt = 32; + + unsigned i; + for(i = 0; i < m_num_pnt; i++) + { + m_xp[i] = double(i) / double(m_num_pnt - 1); + m_yp[i] = 0.5; + } + calc_spline_box(); + update_spline(); + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::border_width(double t, double extra) + { + m_border_width = t; + m_border_extra = extra; + calc_spline_box(); + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::calc_spline_box() + { + m_xs1 = m_x1 + m_border_width; + m_ys1 = m_y1 + m_border_width; + m_xs2 = m_x2 - m_border_width; + m_ys2 = m_y2 - m_border_width; + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::update_spline() + { + int i; + m_spline.init(m_num_pnt, m_xp, m_yp); + for(i = 0; i < 256; i++) + { + m_spline_values[i] = m_spline.get(double(i) / 255.0); + if(m_spline_values[i] < 0.0) m_spline_values[i] = 0.0; + if(m_spline_values[i] > 1.0) m_spline_values[i] = 1.0; + m_spline_values8[i] = (int8u)(m_spline_values[i] * 255.0); + } + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::calc_curve() + { + int i; + m_curve_pnt.remove_all(); + m_curve_pnt.move_to(m_xs1, m_ys1 + (m_ys2 - m_ys1) * m_spline_values[0]); + for(i = 1; i < 256; i++) + { + m_curve_pnt.line_to(m_xs1 + (m_xs2 - m_xs1) * double(i) / 255.0, + m_ys1 + (m_ys2 - m_ys1) * m_spline_values[i]); + } + } + + + //------------------------------------------------------------------------ + double spline_ctrl_impl::calc_xp(unsigned idx) + { + return m_xs1 + (m_xs2 - m_xs1) * m_xp[idx]; + } + + + //------------------------------------------------------------------------ + double spline_ctrl_impl::calc_yp(unsigned idx) + { + return m_ys1 + (m_ys2 - m_ys1) * m_yp[idx]; + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::set_xp(unsigned idx, double val) + { + if(val < 0.0) val = 0.0; + if(val > 1.0) val = 1.0; + + if(idx == 0) + { + val = 0.0; + } + else if(idx == m_num_pnt - 1) + { + val = 1.0; + } + else + { + if(val < m_xp[idx - 1] + 0.001) val = m_xp[idx - 1] + 0.001; + if(val > m_xp[idx + 1] - 0.001) val = m_xp[idx + 1] - 0.001; + } + m_xp[idx] = val; + } + + //------------------------------------------------------------------------ + void spline_ctrl_impl::set_yp(unsigned idx, double val) + { + if(val < 0.0) val = 0.0; + if(val > 1.0) val = 1.0; + m_yp[idx] = val; + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::point(unsigned idx, double x, double y) + { + if(idx < m_num_pnt) + { + set_xp(idx, x); + set_yp(idx, y); + } + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::value(unsigned idx, double y) + { + if(idx < m_num_pnt) + { + set_yp(idx, y); + } + } + + //------------------------------------------------------------------------ + double spline_ctrl_impl::value(double x) const + { + x = m_spline.get(x); + if(x < 0.0) x = 0.0; + if(x > 1.0) x = 1.0; + return x; + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::rewind(unsigned idx) + { + unsigned i; + + m_idx = idx; + + switch(idx) + { + default: + + case 0: // Background + m_vertex = 0; + m_vx[0] = m_x1 - m_border_extra; + m_vy[0] = m_y1 - m_border_extra; + m_vx[1] = m_x2 + m_border_extra; + m_vy[1] = m_y1 - m_border_extra; + m_vx[2] = m_x2 + m_border_extra; + m_vy[2] = m_y2 + m_border_extra; + m_vx[3] = m_x1 - m_border_extra; + m_vy[3] = m_y2 + m_border_extra; + break; + + case 1: // Border + m_vertex = 0; + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y2; + m_vx[4] = m_x1 + m_border_width; + m_vy[4] = m_y1 + m_border_width; + m_vx[5] = m_x1 + m_border_width; + m_vy[5] = m_y2 - m_border_width; + m_vx[6] = m_x2 - m_border_width; + m_vy[6] = m_y2 - m_border_width; + m_vx[7] = m_x2 - m_border_width; + m_vy[7] = m_y1 + m_border_width; + break; + + case 2: // Curve + calc_curve(); + m_curve_poly.width(m_curve_width); + m_curve_poly.rewind(0); + break; + + + case 3: // Inactive points + m_curve_pnt.remove_all(); + for(i = 0; i < m_num_pnt; i++) + { + if(int(i) != m_active_pnt) + { + m_ellipse.init(calc_xp(i), calc_yp(i), + m_point_size, m_point_size, 32); + m_curve_pnt.concat_path(m_ellipse); + } + } + m_curve_poly.rewind(0); + break; + + + case 4: // Active point + m_curve_pnt.remove_all(); + if(m_active_pnt >= 0) + { + m_ellipse.init(calc_xp(m_active_pnt), calc_yp(m_active_pnt), + m_point_size, m_point_size, 32); + + m_curve_pnt.concat_path(m_ellipse); + } + m_curve_poly.rewind(0); + break; + + } + } + + + //------------------------------------------------------------------------ + unsigned spline_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; + if(m_vertex >= 8) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 2: + cmd = m_curve_poly.vertex(x, y); + break; + + case 3: + case 4: + cmd = m_curve_pnt.vertex(x, y); + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + + return cmd; + } + + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::active_point(int i) + { + m_active_pnt = i; + } + + + //------------------------------------------------------------------------ + bool spline_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; + } + + + //------------------------------------------------------------------------ + bool spline_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + unsigned i; + for(i = 0; i < m_num_pnt; i++) + { + double xp = calc_xp(i); + double yp = calc_yp(i); + if(calc_distance(x, y, xp, yp) <= m_point_size + 1) + { + m_pdx = xp - x; + m_pdy = yp - y; + m_active_pnt = m_move_pnt = int(i); + return true; + } + } + return false; + } + + + //------------------------------------------------------------------------ + bool spline_ctrl_impl::on_mouse_button_up(double, double) + { + if(m_move_pnt >= 0) + { + m_move_pnt = -1; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool spline_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + if(!button_flag) + { + return on_mouse_button_up(x, y); + } + + if(m_move_pnt >= 0) + { + double xp = x + m_pdx; + double yp = y + m_pdy; + + set_xp(m_move_pnt, (xp - m_xs1) / (m_xs2 - m_xs1)); + set_yp(m_move_pnt, (yp - m_ys1) / (m_ys2 - m_ys1)); + + update_spline(); + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool spline_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + double kx = 0.0; + double ky = 0.0; + bool ret = false; + if(m_active_pnt >= 0) + { + kx = m_xp[m_active_pnt]; + ky = m_yp[m_active_pnt]; + if(left) { kx -= 0.001; ret = true; } + if(right) { kx += 0.001; ret = true; } + if(down) { ky -= 0.001; ret = true; } + if(up) { ky += 0.001; ret = true; } + } + if(ret) + { + set_xp(m_active_pnt, kx); + set_yp(m_active_pnt, ky); + update_spline(); + } + return ret; + } + + + + +} + diff --git a/src/platform/AmigaOS/Makefile.am b/src/platform/AmigaOS/Makefile.am new file mode 100644 index 0000000..474153c --- /dev/null +++ b/src/platform/AmigaOS/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST=agg_platform_support.cpp diff --git a/src/platform/AmigaOS/agg_platform_support.cpp b/src/platform/AmigaOS/agg_platform_support.cpp new file mode 100644 index 0000000..b14d09c --- /dev/null +++ b/src/platform/AmigaOS/agg_platform_support.cpp @@ -0,0 +1,977 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class platform_support +// +//---------------------------------------------------------------------------- + +#include "platform/agg_platform_support.h" +#include "util/agg_color_conv_rgb8.h" + +#include <sys/time.h> +#include <cstring> + +#include <classes/requester.h> +#include <classes/window.h> +#include <datatypes/pictureclass.h> +#include <proto/exec.h> +#include <proto/datatypes.h> +#include <proto/dos.h> +#include <proto/graphics.h> +#include <proto/intuition.h> +#include <proto/keymap.h> +#include <proto/Picasso96API.h> +#include <proto/utility.h> + +Library* DataTypesBase = 0; +Library* GraphicsBase = 0; +Library* IntuitionBase = 0; +Library* KeymapBase = 0; +Library* P96Base = 0; + +DataTypesIFace* IDataTypes = 0; +GraphicsIFace* IGraphics = 0; +IntuitionIFace* IIntuition = 0; +KeymapIFace* IKeymap = 0; +P96IFace* IP96 = 0; + +Class* RequesterClass = 0; +Class* WindowClass = 0; + + +namespace agg +{ + void handle_idcmp(Hook* hook, APTR win, IntuiMessage* msg); + + //------------------------------------------------------------------------ + class platform_specific + { + public: + platform_specific(platform_support& support, pix_format_e format, + bool flip_y); + ~platform_specific(); + bool handle_input(); + bool load_img(const char* file, unsigned idx, rendering_buffer* rbuf); + bool create_img(unsigned idx, rendering_buffer* rbuf, unsigned width, + unsigned height); + bool make_bitmap(); + public: + platform_support& m_support; + RGBFTYPE m_ftype; + pix_format_e m_format; + unsigned m_bpp; + BitMap* m_bitmap; + bool m_flip_y; + uint16 m_width; + uint16 m_height; + APTR m_window_obj; + Window* m_window; + Hook* m_idcmp_hook; + unsigned m_input_flags; + bool m_dragging; + double m_start_time; + uint16 m_last_key; + BitMap* m_img_bitmaps[platform_support::max_images]; + }; + + //------------------------------------------------------------------------ + platform_specific::platform_specific(platform_support& support, + pix_format_e format, bool flip_y) : + m_support(support), + m_ftype(RGBFB_NONE), + m_format(format), + m_bpp(0), + m_bitmap(0), + m_flip_y(flip_y), + m_width(0), + m_height(0), + m_window_obj(0), + m_window(0), + m_idcmp_hook(0), + m_input_flags(0), + m_dragging(false), + m_start_time(0.0), + m_last_key(0) + { + switch ( format ) + { + case pix_format_gray8: + // Not supported. + break; + case pix_format_rgb555: + m_ftype = RGBFB_R5G5B5; + m_bpp = 15; + break; + case pix_format_rgb565: + m_ftype = RGBFB_R5G6B5; + m_bpp = 16; + break; + case pix_format_rgb24: + m_ftype = RGBFB_R8G8B8; + m_bpp = 24; + break; + case pix_format_bgr24: + m_ftype = RGBFB_B8G8R8; + m_bpp = 24; + break; + case pix_format_bgra32: + m_ftype = RGBFB_B8G8R8A8; + m_bpp = 32; + break; + case pix_format_abgr32: + m_ftype = RGBFB_A8B8G8R8; + m_bpp = 32; + break; + case pix_format_argb32: + m_ftype = RGBFB_A8R8G8B8; + m_bpp = 32; + break; + case pix_format_rgba32: + m_ftype = RGBFB_R8G8B8A8; + m_bpp = 32; + break; + } + + for ( unsigned i = 0; i < platform_support::max_images; ++i ) + { + m_img_bitmaps[i] = 0; + } + } + + //------------------------------------------------------------------------ + platform_specific::~platform_specific() + { + IIntuition->DisposeObject(m_window_obj); + + IP96->p96FreeBitMap(m_bitmap); + + for ( unsigned i = 0; i < platform_support::max_images; ++i ) + { + IP96->p96FreeBitMap(m_img_bitmaps[i]); + } + + if ( m_idcmp_hook != 0 ) + { + IExec->FreeSysObject(ASOT_HOOK, m_idcmp_hook); + } + } + + //------------------------------------------------------------------------ + bool platform_specific::handle_input() + { + int16 code = 0; + uint32 result = 0; + Object* obj = reinterpret_cast<Object*>(m_window_obj); + + while ( (result = IIntuition->IDoMethod(obj, WM_HANDLEINPUT, + &code)) != WMHI_LASTMSG ) + { + switch ( result & WMHI_CLASSMASK ) + { + case WMHI_CLOSEWINDOW: + return true; + break; + case WMHI_INTUITICK: + if ( !m_support.wait_mode() ) + { + m_support.on_idle(); + } + break; + case WMHI_NEWSIZE: + if ( make_bitmap() ) + { + m_support.trans_affine_resizing(m_width, m_height); + m_support.on_resize(m_width, m_height); + m_support.force_redraw(); + } + break; + } + } + + return false; + } + + //------------------------------------------------------------------------ + bool platform_specific::load_img(const char* file, unsigned idx, + rendering_buffer* rbuf) + { + if ( m_img_bitmaps[idx] != 0 ) + { + IP96->p96FreeBitMap(m_img_bitmaps[idx]); + m_img_bitmaps[idx] = 0; + } + + bool result = false; + + Object* picture = IDataTypes->NewDTObject(const_cast<STRPTR>(file), + DTA_GroupID, GID_PICTURE, + PDTA_DestMode, PMODE_V43, + PDTA_Remap, FALSE, + TAG_END); + if ( picture != 0 ) + { + gpLayout layout; + layout.MethodID = DTM_PROCLAYOUT; + layout.gpl_GInfo = 0; + layout.gpl_Initial = 1; + ULONG loaded = IDataTypes->DoDTMethodA(picture, 0, 0, + reinterpret_cast<Msg>(&layout)); + if ( loaded != 0 ) + { + BitMap* src_bitmap = 0; + IDataTypes->GetDTAttrs(picture, + PDTA_ClassBitMap, &src_bitmap, + TAG_END); + + bool supported = false; + + RGBFTYPE ftype = static_cast<RGBFTYPE>(IP96->p96GetBitMapAttr( + src_bitmap, P96BMA_RGBFORMAT)); + + switch ( ftype ) + { + case RGBFB_R8G8B8: + supported = true; + break; + default: + m_support.message("File uses unsupported graphics mode."); + break; + } + + if ( supported ) { + uint16 width = IP96->p96GetBitMapAttr(src_bitmap, + P96BMA_WIDTH); + uint16 height = IP96->p96GetBitMapAttr(src_bitmap, + P96BMA_HEIGHT); + + m_img_bitmaps[idx] = IP96->p96AllocBitMap(width, height, + m_bpp, BMF_USERPRIVATE, 0, m_ftype); + if ( m_img_bitmaps[idx] != 0 ) + { + int8u* buf = reinterpret_cast<int8u*>( + IP96->p96GetBitMapAttr(m_img_bitmaps[idx], + P96BMA_MEMORY)); + int bpr = IP96->p96GetBitMapAttr(m_img_bitmaps[idx], + P96BMA_BYTESPERROW); + int stride = (m_flip_y) ? -bpr : bpr; + rbuf->attach(buf, width, height, stride); + + // P96 sets the alpha to zero so it can't be used to + // color convert true color modes. + if ( m_bpp == 32 ) + { + RenderInfo ri; + int32 lock = IP96->p96LockBitMap(src_bitmap, + reinterpret_cast<uint8*>(&ri), + sizeof(RenderInfo)); + + rendering_buffer rbuf_src; + rbuf_src.attach( + reinterpret_cast<int8u*>(ri.Memory), + width, height, (m_flip_y) ? + -ri.BytesPerRow : ri.BytesPerRow); + + switch ( m_format ) + { + case pix_format_bgra32: + color_conv(rbuf, &rbuf_src, + color_conv_rgb24_to_bgra32()); + break; + case pix_format_abgr32: + color_conv(rbuf, &rbuf_src, + color_conv_rgb24_to_abgr32()); + break; + case pix_format_argb32: + color_conv(rbuf, &rbuf_src, + color_conv_rgb24_to_argb32()); + break; + case pix_format_rgba32: + color_conv(rbuf, &rbuf_src, + color_conv_rgb24_to_rgba32()); + break; + } + + IP96->p96UnlockBitMap(src_bitmap, lock); + } + else + { + IGraphics->BltBitMap(src_bitmap, 0, 0, + m_img_bitmaps[idx], 0, 0, width, height, + ABC|ABNC, 0xFF, 0); + } + + result = true; + } + } + } + } + + IGraphics->WaitBlit(); + IDataTypes->DisposeDTObject(picture); + + return result; + } + + //------------------------------------------------------------------------ + bool platform_specific::create_img(unsigned idx, rendering_buffer* rbuf, + unsigned width, unsigned height) + { + if ( m_img_bitmaps[idx] != 0 ) + { + IP96->p96FreeBitMap(m_img_bitmaps[idx]); + m_img_bitmaps[idx] = 0; + } + + m_img_bitmaps[idx] = IP96->p96AllocBitMap(width, height, + m_bpp, BMF_USERPRIVATE, m_bitmap, m_ftype); + if ( m_img_bitmaps[idx] != 0 ) + { + int8u* buf = reinterpret_cast<int8u*>( + IP96->p96GetBitMapAttr(m_img_bitmaps[idx], + P96BMA_MEMORY)); + int bpr = IP96->p96GetBitMapAttr(m_img_bitmaps[idx], + P96BMA_BYTESPERROW); + int stride = (m_flip_y) ? -bpr : bpr; + + rbuf->attach(buf, width, height, stride); + + return true; + } + + return false; + } + + //------------------------------------------------------------------------ + bool platform_specific::make_bitmap() + { + uint32 width = 0; + uint32 height = 0; + IIntuition->GetWindowAttrs(m_window, + WA_InnerWidth, &width, + WA_InnerHeight, &height, + TAG_END); + + BitMap* bm = IP96->p96AllocBitMap(width, height, m_bpp, + BMF_USERPRIVATE|BMF_CLEAR, 0, m_ftype); + if ( bm == 0 ) + { + return false; + } + + int8u* buf = reinterpret_cast<int8u*>( + IP96->p96GetBitMapAttr(bm, P96BMA_MEMORY)); + int bpr = IP96->p96GetBitMapAttr(bm, P96BMA_BYTESPERROW); + int stride = (m_flip_y) ? -bpr : bpr; + + m_support.rbuf_window().attach(buf, width, height, stride); + + if ( m_bitmap != 0 ) + { + IP96->p96FreeBitMap(m_bitmap); + m_bitmap = 0; + } + + m_bitmap = bm; + m_width = width; + m_height = height; + + return true; + } + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(*this, format, flip_y)), + m_format(format), + m_bpp(m_specific->m_bpp), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y), + m_initial_width(10), + m_initial_height(10) + { + std::strncpy(m_caption, "Anti-Grain Geometry", 256); + } + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + std::strncpy(m_caption, cap, 256); + if ( m_specific->m_window != 0 ) + { + const char* ignore = reinterpret_cast<const char*>(-1); + IIntuition->SetWindowAttr(m_specific->m_window, + WA_Title, m_caption, sizeof(char*)); + } + } + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + timeval tv; + gettimeofday(&tv, 0); + m_specific->m_start_time = tv.tv_secs + tv.tv_micro/1e6; + } + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + timeval tv; + gettimeofday(&tv, 0); + double end_time = tv.tv_secs + tv.tv_micro/1e6; + + double elasped_seconds = end_time - m_specific->m_start_time; + double elasped_millis = elasped_seconds*1e3; + + return elasped_millis; + } + + //------------------------------------------------------------------------ + void* platform_support::raw_display_handler() + { + return 0; // Not available. + } + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + APTR req = IIntuition->NewObject(RequesterClass, 0, + REQ_TitleText, "Anti-Grain Geometry", + REQ_Image, REQIMAGE_INFO, + REQ_BodyText, msg, + REQ_GadgetText, "_Ok", + TAG_END); + if ( req == 0 ) + { + IDOS->Printf("Message: %s\n", msg); + return; + } + + orRequest reqmsg; + reqmsg.MethodID = RM_OPENREQ; + reqmsg.or_Attrs = 0; + reqmsg.or_Window = m_specific->m_window; + reqmsg.or_Screen = 0; + + IIntuition->IDoMethodA(reinterpret_cast<Object*>(req), + reinterpret_cast<Msg>(&reqmsg)); + IIntuition->DisposeObject(req); + } + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, + unsigned flags) + { + if( m_specific->m_ftype == RGBFB_NONE ) + { + message("Unsupported mode requested."); + return false; + } + + m_window_flags = flags; + + m_specific->m_idcmp_hook = reinterpret_cast<Hook*>( + IExec->AllocSysObjectTags(ASOT_HOOK, + ASOHOOK_Entry, handle_idcmp, + ASOHOOK_Data, this, + TAG_END)); + if ( m_specific->m_idcmp_hook == 0 ) + { + return false; + } + + m_specific->m_window_obj = IIntuition->NewObject(WindowClass, 0, + WA_Title, m_caption, + WA_AutoAdjustDClip, TRUE, + WA_InnerWidth, width, + WA_InnerHeight, height, + WA_Activate, TRUE, + WA_SmartRefresh, TRUE, + WA_NoCareRefresh, TRUE, + WA_CloseGadget, TRUE, + WA_DepthGadget, TRUE, + WA_SizeGadget, (flags & agg::window_resize) ? TRUE : FALSE, + WA_DragBar, TRUE, + WA_AutoAdjust, TRUE, + WA_ReportMouse, TRUE, + WA_RMBTrap, TRUE, + WA_MouseQueue, 1, + WA_IDCMP, + IDCMP_NEWSIZE | + IDCMP_MOUSEBUTTONS | + IDCMP_MOUSEMOVE | + IDCMP_RAWKEY | + IDCMP_INTUITICKS, + WINDOW_IDCMPHook, m_specific->m_idcmp_hook, + WINDOW_IDCMPHookBits, + IDCMP_MOUSEBUTTONS | + IDCMP_MOUSEMOVE | + IDCMP_RAWKEY, + TAG_END); + if ( m_specific->m_window_obj == 0 ) + { + return false; + } + + Object* obj = reinterpret_cast<Object*>(m_specific->m_window_obj); + m_specific->m_window = + reinterpret_cast<Window*>(IIntuition->IDoMethod(obj, WM_OPEN)); + if ( m_specific->m_window == 0 ) + { + return false; + } + + RGBFTYPE ftype = static_cast<RGBFTYPE>(IP96->p96GetBitMapAttr( + m_specific->m_window->RPort->BitMap, P96BMA_RGBFORMAT)); + + switch ( ftype ) + { + case RGBFB_A8R8G8B8: + case RGBFB_B8G8R8A8: + case RGBFB_R5G6B5PC: + break; + default: + message("Unsupported screen mode.\n"); + return false; + } + + if ( !m_specific->make_bitmap() ) + { + return false; + } + + m_initial_width = width; + m_initial_height = height; + + on_init(); + on_resize(width, height); + force_redraw(); + + return true; + } + + //------------------------------------------------------------------------ + int platform_support::run() + { + uint32 window_mask = 0; + IIntuition->GetAttr(WINDOW_SigMask, m_specific->m_window_obj, + &window_mask); + uint32 wait_mask = window_mask | SIGBREAKF_CTRL_C; + + bool done = false; + + while ( !done ) + { + uint32 sig_mask = IExec->Wait(wait_mask); + if ( sig_mask & SIGBREAKF_CTRL_C ) + { + done = true; + } + else + { + done = m_specific->handle_input(); + } + } + + return 0; + } + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const + { + return ".bmp"; + } + + //------------------------------------------------------------------------ + const char* platform_support::full_file_name(const char* file_name) + { + return file_name; + } + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if ( idx < max_images ) + { + static char fn[1024]; + std::strncpy(fn, file, 1024); + int len = std::strlen(fn); + if ( len < 4 || std::strcmp(fn + len - 4, ".bmp") != 0 ) + { + std::strncat(fn, ".bmp", 1024); + } + + return m_specific->load_img(fn, idx, &m_rbuf_img[idx]); + } + + return false; + } + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + message("Not supported"); + return false; + } + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, + unsigned height) + { + if ( idx < max_images ) + { + if ( width == 0 ) + { + width = m_specific->m_width; + } + + if ( height == 0 ) + { + height = m_specific->m_height; + } + + return m_specific->create_img(idx, &m_rbuf_img[idx], width, + height); + } + + return false; + } + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + on_draw(); + update_window(); + } + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + // Note this function does automatic color conversion. + IGraphics->BltBitMapRastPort(m_specific->m_bitmap, 0, 0, + m_specific->m_window->RPort, m_specific->m_window->BorderLeft, + m_specific->m_window->BorderTop, m_specific->m_width, + m_specific->m_height, ABC|ABNC); + } + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} + + //------------------------------------------------------------------------ + void handle_idcmp(Hook* hook, APTR obj, IntuiMessage* msg) + { + platform_support* app = + reinterpret_cast<platform_support*>(hook->h_Data); + Window* window = app->m_specific->m_window; + + int16 x = msg->MouseX - window->BorderLeft; + + int16 y = 0; + if ( app->flip_y() ) + { + y = window->Height - window->BorderBottom - msg->MouseY; + } + else + { + y = msg->MouseY - window->BorderTop; + } + + switch ( msg->Class ) + { + case IDCMP_MOUSEBUTTONS: + if ( msg->Code & IECODE_UP_PREFIX ) + { + if ( msg->Code == SELECTUP ) + { + app->m_specific->m_input_flags = mouse_left; + app->m_specific->m_dragging = false; + } + else if ( msg->Code == MENUUP ) + { + app->m_specific->m_input_flags = mouse_right; + app->m_specific->m_dragging = false; + } + else + { + return; + } + + + if ( app->m_ctrls.on_mouse_button_up(x, y) ) + { + app->on_ctrl_change(); + app->force_redraw(); + } + + app->on_mouse_button_up(x, y, app->m_specific->m_input_flags); + } + else + { + if ( msg->Code == SELECTDOWN ) + { + app->m_specific->m_input_flags = mouse_left; + app->m_specific->m_dragging = true; + } + else if ( msg->Code == MENUDOWN ) + { + app->m_specific->m_input_flags = mouse_right; + app->m_specific->m_dragging = true; + } + else + { + return; + } + + app->m_ctrls.set_cur(x, y); + if ( app->m_ctrls.on_mouse_button_down(x, y) ) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + if ( app->m_ctrls.in_rect(x, y) ) + { + if ( app->m_ctrls.set_cur(x, y) ) + { + app->on_ctrl_change(); + app->force_redraw(); + } + } + else + { + app->on_mouse_button_down(x, y, + app->m_specific->m_input_flags); + } + } + } + break; + case IDCMP_MOUSEMOVE: + if ( app->m_specific->m_dragging ) { + if ( app->m_ctrls.on_mouse_move(x, y, + app->m_specific->m_input_flags & mouse_left) != 0 ) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + if ( !app->m_ctrls.in_rect(x, y) ) + { + app->on_mouse_move(x, y, + app->m_specific->m_input_flags); + } + } + } + break; + case IDCMP_RAWKEY: + { + static InputEvent ie = { 0 }; + ie.ie_Class = IECLASS_RAWKEY; + ie.ie_Code = msg->Code; + ie.ie_Qualifier = msg->Qualifier; + + static const unsigned BUF_SIZE = 16; + static char key_buf[BUF_SIZE]; + int16 num_chars = IKeymap->MapRawKey(&ie, key_buf, BUF_SIZE, 0); + + uint32 code = 0x00000000; + switch ( num_chars ) + { + case 1: + code = key_buf[0]; + break; + case 2: + code = key_buf[0]<<8 | key_buf[1]; + break; + case 3: + code = key_buf[0]<<16 | key_buf[1]<<8 | key_buf[2]; + break; + } + + uint16 key_code = 0; + + if ( num_chars == 1 ) + { + if ( code >= IECODE_ASCII_FIRST && code <= IECODE_ASCII_LAST ) + { + key_code = code; + } + } + + if ( key_code == 0 ) + { + switch ( code ) + { + case 0x00000008: key_code = key_backspace; break; + case 0x00000009: key_code = key_tab; break; + case 0x0000000D: key_code = key_return; break; + case 0x0000001B: key_code = key_escape; break; + case 0x0000007F: key_code = key_delete; break; + case 0x00009B41: + case 0x00009B54: key_code = key_up; break; + case 0x00009B42: + case 0x00009B53: key_code = key_down; break; + case 0x00009B43: + case 0x009B2040: key_code = key_right; break; + case 0x00009B44: + case 0x009B2041: key_code = key_left; break; + case 0x009B307E: key_code = key_f1; break; + case 0x009B317E: key_code = key_f2; break; + case 0x009B327E: key_code = key_f3; break; + case 0x009B337E: key_code = key_f4; break; + case 0x009B347E: key_code = key_f5; break; + case 0x009B357E: key_code = key_f6; break; + case 0x009B367E: key_code = key_f7; break; + case 0x009B377E: key_code = key_f8; break; + case 0x009B387E: key_code = key_f9; break; + case 0x009B397E: key_code = key_f10; break; + case 0x009B3F7E: key_code = key_scrollock; break; + } + } + + if ( ie.ie_Code & IECODE_UP_PREFIX ) + { + if ( app->m_specific->m_last_key != 0 ) + { + bool left = (key_code == key_left) ? true : false; + bool right = (key_code == key_right) ? true : false; + bool down = (key_code == key_down) ? true : false; + bool up = (key_code == key_up) ? true : false; + + if ( app->m_ctrls.on_arrow_keys(left, right, down, up) ) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + app->on_key(x, y, app->m_specific->m_last_key, 0); + } + + app->m_specific->m_last_key = 0; + } + } + else + { + app->m_specific->m_last_key = key_code; + } + break; + } + default: + break; + } + } +} + +//---------------------------------------------------------------------------- +int agg_main(int argc, char* argv[]); +bool open_libs(); +void close_libs(); + +//---------------------------------------------------------------------------- +bool open_libs() +{ + DataTypesBase = IExec->OpenLibrary("datatypes.library", 51); + GraphicsBase = IExec->OpenLibrary("graphics.library", 51); + IntuitionBase = IExec->OpenLibrary("intuition.library", 51); + KeymapBase = IExec->OpenLibrary("keymap.library", 51); + P96Base = IExec->OpenLibrary("Picasso96API.library", 2); + + IDataTypes = reinterpret_cast<DataTypesIFace*>( + IExec->GetInterface(DataTypesBase, "main", 1, 0)); + IGraphics = reinterpret_cast<GraphicsIFace*>( + IExec->GetInterface(GraphicsBase, "main", 1, 0)); + IIntuition = reinterpret_cast<IntuitionIFace*>( + IExec->GetInterface(IntuitionBase, "main", 1, 0)); + IKeymap = reinterpret_cast<KeymapIFace*>( + IExec->GetInterface(KeymapBase, "main", 1, 0)); + IP96 = reinterpret_cast<P96IFace*>( + IExec->GetInterface(P96Base, "main", 1, 0)); + + if ( IDataTypes == 0 || + IGraphics == 0 || + IIntuition == 0 || + IKeymap == 0 || + IP96 == 0 ) + { + close_libs(); + return false; + } + else + { + return true; + } +} + +//---------------------------------------------------------------------------- +void close_libs() +{ + IExec->DropInterface(reinterpret_cast<Interface*>(IP96)); + IExec->DropInterface(reinterpret_cast<Interface*>(IKeymap)); + IExec->DropInterface(reinterpret_cast<Interface*>(IIntuition)); + IExec->DropInterface(reinterpret_cast<Interface*>(IGraphics)); + IExec->DropInterface(reinterpret_cast<Interface*>(IDataTypes)); + + IExec->CloseLibrary(P96Base); + IExec->CloseLibrary(KeymapBase); + IExec->CloseLibrary(IntuitionBase); + IExec->CloseLibrary(GraphicsBase); + IExec->CloseLibrary(DataTypesBase); +} + +//---------------------------------------------------------------------------- +int main(int argc, char* argv[]) +{ + if ( !open_libs() ) { + IDOS->Printf("Can't open libraries.\n"); + return -1; + } + + ClassLibrary* requester = + IIntuition->OpenClass("requester.class", 51, &RequesterClass); + ClassLibrary* window = + IIntuition->OpenClass("window.class", 51, &WindowClass); + if ( requester == 0 || window == 0 ) + { + IDOS->Printf("Can't open classes.\n"); + IIntuition->CloseClass(requester); + IIntuition->CloseClass(window); + close_libs(); + return -1; + } + + int rc = agg_main(argc, argv); + + IIntuition->CloseClass(window); + IIntuition->CloseClass(requester); + close_libs(); + + return rc; +} diff --git a/src/platform/BeOS/Makefile.am b/src/platform/BeOS/Makefile.am new file mode 100644 index 0000000..474153c --- /dev/null +++ b/src/platform/BeOS/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST=agg_platform_support.cpp diff --git a/src/platform/BeOS/agg_platform_support.cpp b/src/platform/BeOS/agg_platform_support.cpp new file mode 100644 index 0000000..3f87aa0 --- /dev/null +++ b/src/platform/BeOS/agg_platform_support.cpp @@ -0,0 +1,990 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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: superstippi@gmx.de +//---------------------------------------------------------------------------- +// +// class platform_support +// +//---------------------------------------------------------------------------- + +#include <new> +#include <cstdio> + +#include <Alert.h> +#include <Application.h> +#include <Bitmap.h> +#include <Message.h> +#include <MessageRunner.h> +#include <Messenger.h> +#include <Path.h> +#include <Roster.h> +#include <TranslationUtils.h> +#include <View.h> +#include <Window.h> + +#include <cstring> +#include "platform/agg_platform_support.h" +#include "util/agg_color_conv_rgb8.h" + +using std::nothrow; + + +static void +attach_buffer_to_BBitmap(agg::rendering_buffer& buffer, BBitmap* bitmap, bool flipY) +{ + uint8* bits = (uint8*)bitmap->Bits(); + uint32 width = bitmap->Bounds().IntegerWidth() + 1; + uint32 height = bitmap->Bounds().IntegerHeight() + 1; + int32 bpr = bitmap->BytesPerRow(); + if (flipY) { +// XXX: why don't I have to do this?!? +// bits += bpr * (height - 1); + bpr = -bpr; + } + buffer.attach(bits, width, height, bpr); +} + + +static color_space +pix_format_to_color_space(agg::pix_format_e format) +{ + color_space bitmapFormat = B_NO_COLOR_SPACE; + switch (format) { + case agg::pix_format_rgb555: + + bitmapFormat = B_RGB15; + break; + + case agg::pix_format_rgb565: + + bitmapFormat = B_RGB16; + break; + + case agg::pix_format_rgb24: + case agg::pix_format_bgr24: + + bitmapFormat = B_RGB24; + break; + + case agg::pix_format_rgba32: + case agg::pix_format_argb32: + case agg::pix_format_abgr32: + case agg::pix_format_bgra32: + + bitmapFormat = B_RGBA32; + break; + } + return bitmapFormat; +} + + +// #pragma mark - + + +class AGGView : public BView { + public: + AGGView(BRect frame, agg::platform_support* agg, + agg::pix_format_e format, bool flipY); + virtual ~AGGView(); + + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); + + virtual void MessageReceived(BMessage* message); + virtual void Draw(BRect updateRect); + virtual void FrameResized(float width, float height); + + virtual void KeyDown(const char* bytes, int32 numBytes); + + virtual void MouseDown(BPoint where); + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMesage); + virtual void MouseUp(BPoint where); + + BBitmap* Bitmap() const; + + uint8 LastKeyDown() const; + uint32 MouseButtons(); + + void Update(); + void ForceRedraw(); + + unsigned GetKeyFlags(); + + private: + BBitmap* fBitmap; + agg::pix_format_e fFormat; + bool fFlipY; + + agg::platform_support* fAGG; + + uint32 fMouseButtons; + int32 fMouseX; + int32 fMouseY; + + uint8 fLastKeyDown; + + bool fRedraw; + + BMessageRunner* fPulse; + bigtime_t fLastPulse; + bool fEnableTicks; +}; + +AGGView::AGGView(BRect frame, + agg::platform_support* agg, + agg::pix_format_e format, + bool flipY) + : BView(frame, "AGG View", B_FOLLOW_ALL, + B_FRAME_EVENTS | B_WILL_DRAW), + fFormat(format), + fFlipY(flipY), + + fAGG(agg), + + fMouseButtons(0), + fMouseX(-1), + fMouseY(-1), + + fLastKeyDown(0), + + fRedraw(true), + + fPulse(NULL), + fLastPulse(0), + fEnableTicks(true) +{ + SetViewColor(B_TRANSPARENT_32_BIT); + + frame.OffsetTo(0.0, 0.0); + fBitmap = new BBitmap(frame, 0, pix_format_to_color_space(fFormat)); + if (fBitmap->IsValid()) { + attach_buffer_to_BBitmap(fAGG->rbuf_window(), fBitmap, fFlipY); + } else { + delete fBitmap; + fBitmap = NULL; + } +} + + +AGGView::~AGGView() +{ + delete fBitmap; + delete fPulse; +} + + +void +AGGView::AttachedToWindow() +{ + BMessage message('tick'); + BMessenger target(this, Looper()); + delete fPulse; +// BScreen screen; +// TODO: calc screen retrace + fPulse = new BMessageRunner(target, &message, 40000); + + // make sure we call this once + fAGG->on_resize(Bounds().IntegerWidth() + 1, + Bounds().IntegerHeight() + 1); + MakeFocus(); +} + + +void +AGGView::DetachedFromWindow() +{ + delete fPulse; + fPulse = NULL; +} + + +void +AGGView::MessageReceived(BMessage* message) +{ + bigtime_t now = system_time(); + switch (message->what) { + case 'tick': + // drop messages that have piled up + if (/*now - fLastPulse > 30000*/fEnableTicks) { + fLastPulse = now; + if (!fAGG->wait_mode()) + fAGG->on_idle(); + Window()->PostMessage('entk', this); + fEnableTicks = false; + } else { +// printf("dropping tick message (%lld)\n", now - fLastPulse); + } + break; + case 'entk': + fEnableTicks = true; + if (now - fLastPulse > 30000) { + fLastPulse = now; + if (!fAGG->wait_mode()) + fAGG->on_idle(); + } + break; + default: + BView::MessageReceived(message); + break; + } +} + + +void +AGGView::Draw(BRect updateRect) +{ + if (fBitmap) { + if (fRedraw) { + fAGG->on_draw(); + fRedraw = false; + } + if (fFormat == agg::pix_format_bgra32) { + DrawBitmap(fBitmap, updateRect, updateRect); + } else { + BBitmap* bitmap = new BBitmap(fBitmap->Bounds(), 0, B_RGBA32); + + agg::rendering_buffer rbufSrc; + attach_buffer_to_BBitmap(rbufSrc, fBitmap, false); + + agg::rendering_buffer rbufDst; + attach_buffer_to_BBitmap(rbufDst, bitmap, false); + + switch(fFormat) { + case agg::pix_format_rgb555: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_rgb555_to_bgra32()); + break; + case agg::pix_format_rgb565: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_rgb565_to_bgra32()); + break; + case agg::pix_format_rgb24: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_rgb24_to_bgra32()); + break; + case agg::pix_format_bgr24: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_bgr24_to_bgra32()); + break; + case agg::pix_format_rgba32: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_rgba32_to_bgra32()); + break; + case agg::pix_format_argb32: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_argb32_to_bgra32()); + break; + case agg::pix_format_abgr32: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_abgr32_to_bgra32()); + break; + case agg::pix_format_bgra32: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_bgra32_to_bgra32()); + break; + } + DrawBitmap(bitmap, updateRect, updateRect); + delete bitmap; + } + } else { + FillRect(updateRect); + } +} + + +void +AGGView::FrameResized(float width, float height) +{ + BRect r(0.0, 0.0, width, height); + BBitmap* bitmap = new BBitmap(r, 0, pix_format_to_color_space(fFormat)); + if (bitmap->IsValid()) { + delete fBitmap; + fBitmap = bitmap; + attach_buffer_to_BBitmap(fAGG->rbuf_window(), fBitmap, fFlipY); + + fAGG->trans_affine_resizing((int)width + 1, + (int)height + 1); + + // pass the event on to AGG + fAGG->on_resize((int)width + 1, (int)height + 1); + + fRedraw = true; + Invalidate(); + } else + delete bitmap; +} + + +void +AGGView::KeyDown(const char* bytes, int32 numBytes) +{ + if (bytes && numBytes > 0) { + fLastKeyDown = bytes[0]; + + bool left = false; + bool up = false; + bool right = false; + bool down = false; + + switch (fLastKeyDown) { + + case B_LEFT_ARROW: + left = true; + break; + + case B_UP_ARROW: + up = true; + break; + + case B_RIGHT_ARROW: + right = true; + break; + + case B_DOWN_ARROW: + down = true; + break; + } + +/* case key_f2: +fAGG->copy_window_to_img(agg::platform_support::max_images - 1); +fAGG->save_img(agg::platform_support::max_images - 1, "screenshot"); +break; +}*/ + + + if (fAGG->m_ctrls.on_arrow_keys(left, right, down, up)) { + fAGG->on_ctrl_change(); + fAGG->force_redraw(); + } else { + fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags()); + } +// fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags()); + + } +} + + +void +AGGView::MouseDown(BPoint where) +{ + BMessage* currentMessage = Window()->CurrentMessage(); + if (currentMessage) { + if (currentMessage->FindInt32("buttons", (int32*)&fMouseButtons) < B_OK) + fMouseButtons = B_PRIMARY_MOUSE_BUTTON; + } else + fMouseButtons = B_PRIMARY_MOUSE_BUTTON; + + fMouseX = (int)where.x; + fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; + + // pass the event on to AGG + if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) { + // left mouse button -> see if to handle in controls + fAGG->m_ctrls.set_cur(fMouseX, fMouseY); + if (fAGG->m_ctrls.on_mouse_button_down(fMouseX, fMouseY)) { + fAGG->on_ctrl_change(); + fAGG->force_redraw(); + } else { + if (fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) { + if (fAGG->m_ctrls.set_cur(fMouseX, fMouseY)) { + fAGG->on_ctrl_change(); + fAGG->force_redraw(); + } + } else { + fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags()); + } + } + } else if (fMouseButtons & B_SECONDARY_MOUSE_BUTTON) { + // right mouse button -> simple + fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags()); + } + SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); +} + + +void +AGGView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMesage) +{ + // workarround missed mouse up events + // (if we react too slowly, app_server might have dropped events) + BMessage* currentMessage = Window()->CurrentMessage(); + int32 buttons = 0; + if (currentMessage->FindInt32("buttons", &buttons) < B_OK) { + buttons = 0; + } + if (!buttons) + MouseUp(where); + + fMouseX = (int)where.x; + fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; + + // pass the event on to AGG + if (fAGG->m_ctrls.on_mouse_move(fMouseX, fMouseY, + (GetKeyFlags() & agg::mouse_left) != 0)) { + fAGG->on_ctrl_change(); + fAGG->force_redraw(); + } else { + if (!fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) { + fAGG->on_mouse_move(fMouseX, fMouseY, GetKeyFlags()); + } + } +} + + +void +AGGView::MouseUp(BPoint where) +{ + fMouseX = (int)where.x; + fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; + + // pass the event on to AGG + if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) { + fMouseButtons = 0; + + if (fAGG->m_ctrls.on_mouse_button_up(fMouseX, fMouseY)) { + fAGG->on_ctrl_change(); + fAGG->force_redraw(); + } + fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags()); + } else if (fMouseButtons == B_SECONDARY_MOUSE_BUTTON) { + fMouseButtons = 0; + + fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags()); + } +} + + +BBitmap* +AGGView::Bitmap() const +{ + return fBitmap; +} + + +uint8 +AGGView::LastKeyDown() const +{ + return fLastKeyDown; +} + + +uint32 +AGGView::MouseButtons() +{ + uint32 buttons = 0; + if (LockLooper()) { + buttons = fMouseButtons; + UnlockLooper(); + } + return buttons; +} + + +void +AGGView::Update() +{ + // trigger display update + if (LockLooper()) { + Invalidate(); + UnlockLooper(); + } +} + + +void +AGGView::ForceRedraw() +{ + // force a redraw (fRedraw = true;) + // and trigger display update + if (LockLooper()) { + fRedraw = true; + Invalidate(); + UnlockLooper(); + } +} + + +unsigned +AGGView::GetKeyFlags() +{ + uint32 buttons = fMouseButtons; + uint32 mods = modifiers(); + unsigned flags = 0; + if (buttons & B_PRIMARY_MOUSE_BUTTON) flags |= agg::mouse_left; + if (buttons & B_SECONDARY_MOUSE_BUTTON) flags |= agg::mouse_right; + if (mods & B_SHIFT_KEY) flags |= agg::kbd_shift; + if (mods & B_COMMAND_KEY) flags |= agg::kbd_ctrl; + return flags; +} + +// #pragma mark - + + +class AGGWindow : public BWindow { + public: + AGGWindow() + : BWindow(BRect(-50.0, -50.0, -10.0, -10.0), + "AGG Application", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS) + { + } + + virtual bool QuitRequested() + { + be_app->PostMessage(B_QUIT_REQUESTED); + return true; + } + + bool Init(BRect frame, agg::platform_support* agg, agg::pix_format_e format, + bool flipY, uint32 flags) + { + MoveTo(frame.LeftTop()); + ResizeTo(frame.Width(), frame.Height()); + + SetFlags(flags); + + frame.OffsetTo(0.0, 0.0); + fView = new AGGView(frame, agg, format, flipY); + AddChild(fView); + + return fView->Bitmap() != NULL; + } + + + AGGView* View() const + { + return fView; + } + private: + AGGView* fView; +}; + +// #pragma mark - + + +class AGGApplication : public BApplication { + public: + AGGApplication() + : BApplication("application/x-vnd.AGG-AGG") + { + fWindow = new AGGWindow(); + } + + virtual void ReadyToRun() + { + if (fWindow) { + fWindow->Show(); + } + } + + virtual bool Init(agg::platform_support* agg, int width, int height, + agg::pix_format_e format, bool flipY, uint32 flags) + { + BRect r(50.0, 50.0, + 50.0 + width - 1.0, + 50.0 + height - 1.0); + uint32 windowFlags = B_ASYNCHRONOUS_CONTROLS; + if (!(flags & agg::window_resize)) + windowFlags |= B_NOT_RESIZABLE; + + return fWindow->Init(r, agg, format, flipY, windowFlags);; + } + + + AGGWindow* Window() const + { + return fWindow; + } + + private: + AGGWindow* fWindow; +}; + + +// #pragma mark - + + +namespace agg +{ + +class platform_specific { + public: + platform_specific(agg::platform_support* agg, + agg::pix_format_e format, bool flip_y) + : fAGG(agg), + fApp(NULL), + fFormat(format), + fFlipY(flip_y), + fTimerStart(system_time()) + { + memset(fImages, 0, sizeof(fImages)); + fApp = new AGGApplication(); + fAppPath[0] = 0; + // figure out where we're running from + app_info info; + status_t ret = fApp->GetAppInfo(&info); + if (ret >= B_OK) { + BPath path(&info.ref); + ret = path.InitCheck(); + if (ret >= B_OK) { + ret = path.GetParent(&path); + if (ret >= B_OK) { + std::sprintf(fAppPath, "%s", path.Path()); + } else { + std::fprintf(stderr, "getting app parent folder failed: %s\n", std::strerror(ret)); + } + } else { + std::fprintf(stderr, "making app path failed: %s\n", std::strerror(ret)); + } + } else { + std::fprintf(stderr, "GetAppInfo() failed: %s\n", std::strerror(ret)); + } + } + ~platform_specific() + { + for (int32 i = 0; i < agg::platform_support::max_images; i++) + delete fImages[i]; + delete fApp; + } + + bool Init(int width, int height, unsigned flags) + { + return fApp->Init(fAGG, width, height, fFormat, fFlipY, flags); + } + + int Run() + { + status_t ret = B_NO_INIT; + if (fApp) { + fApp->Run(); + ret = B_OK; + } + return ret; + } + + void SetTitle(const char* title) + { + if (fApp && fApp->Window() && fApp->Window()->Lock()) { + fApp->Window()->SetTitle(title); + fApp->Window()->Unlock(); + } + } + void StartTimer() + { + fTimerStart = system_time(); + } + double ElapsedTime() const + { + return (system_time() - fTimerStart) / 1000.0; + } + + void ForceRedraw() + { + fApp->Window()->View()->ForceRedraw(); + } + void UpdateWindow() + { + fApp->Window()->View()->Update(); + } + + + agg::platform_support* fAGG; + AGGApplication* fApp; + agg::pix_format_e fFormat; + bool fFlipY; + bigtime_t fTimerStart; + BBitmap* fImages[agg::platform_support::max_images]; + + char fAppPath[B_PATH_NAME_LENGTH]; + char fFilePath[B_PATH_NAME_LENGTH]; +}; + + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(this, format, flip_y)), + m_format(format), + m_bpp(32/*m_specific->m_bpp*/), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y), + m_initial_width(10), + m_initial_height(10) + { + std::strcpy(m_caption, "Anti-Grain Geometry Application"); + } + + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + std::strcpy(m_caption, cap); + m_specific->SetTitle(cap); + } + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + m_specific->StartTimer(); + } + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + return m_specific->ElapsedTime(); + } + + //------------------------------------------------------------------------ + void* platform_support::raw_display_handler() + { + // TODO: if we ever support BDirectWindow here, that would + // be the frame buffer pointer with offset to the window top left + return NULL; + } + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + BAlert* alert = new BAlert("AGG Message", msg, "Ok"); + alert->Go(/*NULL*/); + } + + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, unsigned flags) + { + m_initial_width = width; + m_initial_height = height; + m_window_flags = flags; + + if (m_specific->Init(width, height, flags)) { + on_init(); + return true; + } + + return false; + } + + + //------------------------------------------------------------------------ + int platform_support::run() + { + return m_specific->Run(); + } + + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const { return ".ppm"; } + + + const char* platform_support::full_file_name(const char* file_name) + { + std::sprintf(m_specific->fFilePath, "%s/%s", m_specific->fAppPath, file_name); + return m_specific->fFilePath; + } + + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if (idx < max_images) + { + char path[B_PATH_NAME_LENGTH]; + std::sprintf(path, "%s/%s%s", m_specific->fAppPath, file, img_ext()); + BBitmap* transBitmap = BTranslationUtils::GetBitmap(path); + if (transBitmap && transBitmap->IsValid()) { + if(transBitmap->ColorSpace() != B_RGB32 && transBitmap->ColorSpace() != B_RGBA32) { + // ups we got a smart ass Translator making our live harder + delete transBitmap; + return false; + } + + color_space format = B_RGB24; + + switch (m_format) { + case pix_format_gray8: + format = B_GRAY8; + break; + case pix_format_rgb555: + format = B_RGB15; + break; + case pix_format_rgb565: + format = B_RGB16; + break; + case pix_format_rgb24: + format = B_RGB24_BIG; + break; + case pix_format_bgr24: + format = B_RGB24; + break; + case pix_format_abgr32: + case pix_format_argb32: + case pix_format_bgra32: + format = B_RGB32; + break; + case pix_format_rgba32: + format = B_RGB32_BIG; + break; + } + BBitmap* bitmap = new (nothrow) BBitmap(transBitmap->Bounds(), 0, format); + if (!bitmap || !bitmap->IsValid()) { + std::fprintf(stderr, "failed to allocate temporary bitmap!\n"); + delete transBitmap; + delete bitmap; + return false; + } + + delete m_specific->fImages[idx]; + + rendering_buffer rbuf_tmp; + attach_buffer_to_BBitmap(rbuf_tmp, transBitmap, m_flip_y); + + m_specific->fImages[idx] = bitmap; + + attach_buffer_to_BBitmap(m_rbuf_img[idx], bitmap, m_flip_y); + + rendering_buffer* dst = &m_rbuf_img[idx]; + + switch(m_format) + { + case pix_format_gray8: + return false; +// color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray8()); break; + break; + + case pix_format_rgb555: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break; + break; + + case pix_format_rgb565: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break; + break; + + case pix_format_rgb24: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break; + break; + + case pix_format_bgr24: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break; + break; + + case pix_format_abgr32: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break; + break; + + case pix_format_argb32: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break; + break; + + case pix_format_bgra32: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break; + break; + + case pix_format_rgba32: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break; + break; + } + delete transBitmap; + + return true; + + } else { + std::fprintf(stderr, "failed to load bitmap: '%s'\n", full_file_name(file)); + } + } + return false; + } + + + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + // TODO: implement using BTranslatorRoster and friends + return false; + } + + + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) + { + if(idx < max_images) + { + if(width == 0) width = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerWidth() + 1; + if(height == 0) height = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerHeight() + 1; + BBitmap* bitmap = new BBitmap(BRect(0.0, 0.0, width - 1, height - 1), 0, B_RGBA32);; + if (bitmap && bitmap->IsValid()) { + delete m_specific->fImages[idx]; + m_specific->fImages[idx] = bitmap; + attach_buffer_to_BBitmap(m_rbuf_img[idx], bitmap, m_flip_y); + return true; + } else { + delete bitmap; + } + } + return false; + } + + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + m_specific->ForceRedraw(); + } + + + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + m_specific->UpdateWindow(); + } + + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} +} + + + + + + +//---------------------------------------------------------------------------- +int agg_main(int argc, char* argv[]); + + + +int +main(int argc, char* argv[]) +{ + return agg_main(argc, argv); +} + + + + diff --git a/src/platform/Makefile.am b/src/platform/Makefile.am new file mode 100644 index 0000000..ebe5e7e --- /dev/null +++ b/src/platform/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = X11 sdl win32 AmigaOS BeOS mac diff --git a/src/platform/X11/Makefile.am b/src/platform/X11/Makefile.am new file mode 100644 index 0000000..57efcf2 --- /dev/null +++ b/src/platform/X11/Makefile.am @@ -0,0 +1,8 @@ +if ENABLE_X11 +lib_LTLIBRARIES = libaggplatformX11.la + +libaggplatformX11_la_LDFLAGS = -version-info @AGG_LIB_VERSION@ +libaggplatformX11_la_SOURCES = agg_platform_support.cpp +libaggplatformX11_la_CXXFLAGS = -I$(top_srcdir)/include @x_includes@ +libaggplatformX11_la_LIBADD = -lX11 +endif diff --git a/src/platform/X11/agg_platform_support.cpp b/src/platform/X11/agg_platform_support.cpp new file mode 100644 index 0000000..e33382b --- /dev/null +++ b/src/platform/X11/agg_platform_support.cpp @@ -0,0 +1,1605 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class platform_support. X11 version. +// +//---------------------------------------------------------------------------- + +#include <cstdio> +#include <cstring> +#include <cstdlib> +#include <cctype> +#include <ctime> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <X11/keysym.h> +#include "agg_basics.h" +#include "agg_pixfmt_gray.h" +#include "agg_pixfmt_rgb.h" +#include "agg_pixfmt_rgba.h" +#include "util/agg_color_conv_rgb8.h" +#include "platform/agg_platform_support.h" + + +namespace agg +{ + //------------------------------------------------------------------------ + class platform_specific + { + public: + platform_specific(pix_format_e format, bool flip_y); + ~platform_specific(); + + void caption(const char* capt); + void put_image(const rendering_buffer* src); + + pix_format_e m_format; + pix_format_e m_sys_format; + int m_byte_order; + bool m_flip_y; + unsigned m_bpp; + unsigned m_sys_bpp; + Display* m_display; + int m_screen; + int m_depth; + Visual* m_visual; + Window m_window; + GC m_gc; + XImage* m_ximg_window; + XSetWindowAttributes m_window_attributes; + Atom m_close_atom; + unsigned char* m_buf_window; + unsigned char* m_buf_img[platform_support::max_images]; + unsigned m_keymap[256]; + + bool m_update_flag; + bool m_resize_flag; + bool m_initialized; + //bool m_wait_mode; + std::clock_t m_sw_start; + }; + + + + //------------------------------------------------------------------------ + platform_specific::platform_specific(pix_format_e format, bool flip_y) : + m_format(format), + m_sys_format(pix_format_undefined), + m_byte_order(LSBFirst), + m_flip_y(flip_y), + m_bpp(0), + m_sys_bpp(0), + m_display(0), + m_screen(0), + m_depth(0), + m_visual(0), + m_window(0), + m_gc(0), + m_ximg_window(0), + m_close_atom(0), + + m_buf_window(0), + + m_update_flag(true), + m_resize_flag(true), + m_initialized(false) + //m_wait_mode(true) + { + std::memset(m_buf_img, 0, sizeof(m_buf_img)); + + unsigned i; + for(i = 0; i < 256; i++) + { + m_keymap[i] = i; + } + + m_keymap[XK_Pause&0xFF] = key_pause; + m_keymap[XK_Clear&0xFF] = key_clear; + + m_keymap[XK_KP_0&0xFF] = key_kp0; + m_keymap[XK_KP_1&0xFF] = key_kp1; + m_keymap[XK_KP_2&0xFF] = key_kp2; + m_keymap[XK_KP_3&0xFF] = key_kp3; + m_keymap[XK_KP_4&0xFF] = key_kp4; + m_keymap[XK_KP_5&0xFF] = key_kp5; + m_keymap[XK_KP_6&0xFF] = key_kp6; + m_keymap[XK_KP_7&0xFF] = key_kp7; + m_keymap[XK_KP_8&0xFF] = key_kp8; + m_keymap[XK_KP_9&0xFF] = key_kp9; + + m_keymap[XK_KP_Insert&0xFF] = key_kp0; + m_keymap[XK_KP_End&0xFF] = key_kp1; + m_keymap[XK_KP_Down&0xFF] = key_kp2; + m_keymap[XK_KP_Page_Down&0xFF] = key_kp3; + m_keymap[XK_KP_Left&0xFF] = key_kp4; + m_keymap[XK_KP_Begin&0xFF] = key_kp5; + m_keymap[XK_KP_Right&0xFF] = key_kp6; + m_keymap[XK_KP_Home&0xFF] = key_kp7; + m_keymap[XK_KP_Up&0xFF] = key_kp8; + m_keymap[XK_KP_Page_Up&0xFF] = key_kp9; + m_keymap[XK_KP_Delete&0xFF] = key_kp_period; + m_keymap[XK_KP_Decimal&0xFF] = key_kp_period; + m_keymap[XK_KP_Divide&0xFF] = key_kp_divide; + m_keymap[XK_KP_Multiply&0xFF] = key_kp_multiply; + m_keymap[XK_KP_Subtract&0xFF] = key_kp_minus; + m_keymap[XK_KP_Add&0xFF] = key_kp_plus; + m_keymap[XK_KP_Enter&0xFF] = key_kp_enter; + m_keymap[XK_KP_Equal&0xFF] = key_kp_equals; + + m_keymap[XK_Up&0xFF] = key_up; + m_keymap[XK_Down&0xFF] = key_down; + m_keymap[XK_Right&0xFF] = key_right; + m_keymap[XK_Left&0xFF] = key_left; + m_keymap[XK_Insert&0xFF] = key_insert; + m_keymap[XK_Home&0xFF] = key_delete; + m_keymap[XK_End&0xFF] = key_end; + m_keymap[XK_Page_Up&0xFF] = key_page_up; + m_keymap[XK_Page_Down&0xFF] = key_page_down; + + m_keymap[XK_F1&0xFF] = key_f1; + m_keymap[XK_F2&0xFF] = key_f2; + m_keymap[XK_F3&0xFF] = key_f3; + m_keymap[XK_F4&0xFF] = key_f4; + m_keymap[XK_F5&0xFF] = key_f5; + m_keymap[XK_F6&0xFF] = key_f6; + m_keymap[XK_F7&0xFF] = key_f7; + m_keymap[XK_F8&0xFF] = key_f8; + m_keymap[XK_F9&0xFF] = key_f9; + m_keymap[XK_F10&0xFF] = key_f10; + m_keymap[XK_F11&0xFF] = key_f11; + m_keymap[XK_F12&0xFF] = key_f12; + m_keymap[XK_F13&0xFF] = key_f13; + m_keymap[XK_F14&0xFF] = key_f14; + m_keymap[XK_F15&0xFF] = key_f15; + + m_keymap[XK_Num_Lock&0xFF] = key_numlock; + m_keymap[XK_Caps_Lock&0xFF] = key_capslock; + m_keymap[XK_Scroll_Lock&0xFF] = key_scrollock; + + switch(m_format) + { + default: break; + case pix_format_gray8: + case pix_format_sgray8: + m_bpp = 8; + break; + + case pix_format_gray16: + m_bpp = 16; + break; + + case pix_format_gray32: + m_bpp = 32; + break; + + case pix_format_rgb565: + case pix_format_rgb555: + m_bpp = 16; + break; + + case pix_format_rgb24: + case pix_format_bgr24: + case pix_format_srgb24: + case pix_format_sbgr24: + m_bpp = 24; + break; + + case pix_format_bgra32: + case pix_format_abgr32: + case pix_format_argb32: + case pix_format_rgba32: + case pix_format_sbgra32: + case pix_format_sabgr32: + case pix_format_sargb32: + case pix_format_srgba32: + m_bpp = 32; + break; + + case pix_format_rgb48: + case pix_format_bgr48: + m_bpp = 48; + break; + + case pix_format_bgra64: + case pix_format_abgr64: + case pix_format_argb64: + case pix_format_rgba64: + m_bpp = 64; + break; + + case pix_format_rgb96: + case pix_format_bgr96: + m_bpp = 96; + break; + + case pix_format_bgra128: + case pix_format_abgr128: + case pix_format_argb128: + case pix_format_rgba128: + m_bpp = 128; + break; + } + m_sw_start = std::clock(); + } + + //------------------------------------------------------------------------ + platform_specific::~platform_specific() + { + } + + //------------------------------------------------------------------------ + void platform_specific::caption(const char* capt) + { + XTextProperty tp; + tp.value = (unsigned char *)capt; + tp.encoding = XA_WM_NAME; + tp.format = 8; + tp.nitems = std::strlen(capt); + XSetWMName(m_display, m_window, &tp); + XStoreName(m_display, m_window, capt); + XSetIconName(m_display, m_window, capt); + XSetWMIconName(m_display, m_window, &tp); + } + + + //------------------------------------------------------------------------ + void platform_specific::put_image(const rendering_buffer* src) + { + if(m_ximg_window == 0) return; + m_ximg_window->data = (char*)m_buf_window; + + if(m_format == m_sys_format) + { + XPutImage(m_display, + m_window, + m_gc, + m_ximg_window, + 0, 0, 0, 0, + src->width(), + src->height()); + } + else + { + int row_len = src->width() * m_sys_bpp / 8; + unsigned char* buf_tmp = + new unsigned char[row_len * src->height()]; + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(buf_tmp, + src->width(), + src->height(), + m_flip_y ? -row_len : row_len); + + switch(m_sys_format) + { + default: break; + case pix_format_rgb555: + switch(m_format) + { + default: break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb555()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); break; + case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb555()); break; + case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb555()); break; + case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb555()); break; + case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb555()); break; + case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb555()); break; + case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb555()); break; + } + break; + + case pix_format_rgb565: + switch(m_format) + { + default: break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb565()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb565()); break; + case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb565()); break; + case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb565()); break; + case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb565()); break; + case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb565()); break; + case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb565()); break; + case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb565()); break; + } + break; + + case pix_format_rgba32: + switch(m_format) + { + default: break; + case pix_format_sgray8: convert<pixfmt_srgba32, pixfmt_sgray8>(&rbuf_tmp, src); break; + case pix_format_gray8: convert<pixfmt_srgba32, pixfmt_gray8>(&rbuf_tmp, src); break; + case pix_format_gray16: convert<pixfmt_srgba32, pixfmt_gray16>(&rbuf_tmp, src); break; + case pix_format_gray32: convert<pixfmt_srgba32, pixfmt_gray32>(&rbuf_tmp, src); break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgba32()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgba32()); break; + case pix_format_srgb24: convert<pixfmt_srgba32, pixfmt_srgb24>(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert<pixfmt_srgba32, pixfmt_sbgr24>(&rbuf_tmp, src); break; + case pix_format_rgb24: convert<pixfmt_srgba32, pixfmt_rgb24>(&rbuf_tmp, src); break; + case pix_format_bgr24: convert<pixfmt_srgba32, pixfmt_bgr24>(&rbuf_tmp, src); break; + case pix_format_srgba32: convert<pixfmt_srgba32, pixfmt_srgba32>(&rbuf_tmp, src); break; + case pix_format_sargb32: convert<pixfmt_srgba32, pixfmt_sargb32>(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert<pixfmt_srgba32, pixfmt_sabgr32>(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert<pixfmt_srgba32, pixfmt_sbgra32>(&rbuf_tmp, src); break; + case pix_format_rgba32: convert<pixfmt_srgba32, pixfmt_rgba32>(&rbuf_tmp, src); break; + case pix_format_argb32: convert<pixfmt_srgba32, pixfmt_argb32>(&rbuf_tmp, src); break; + case pix_format_abgr32: convert<pixfmt_srgba32, pixfmt_abgr32>(&rbuf_tmp, src); break; + case pix_format_bgra32: convert<pixfmt_srgba32, pixfmt_bgra32>(&rbuf_tmp, src); break; + case pix_format_rgb48: convert<pixfmt_srgba32, pixfmt_rgb48>(&rbuf_tmp, src); break; + case pix_format_bgr48: convert<pixfmt_srgba32, pixfmt_bgr48>(&rbuf_tmp, src); break; + case pix_format_rgba64: convert<pixfmt_srgba32, pixfmt_rgba64>(&rbuf_tmp, src); break; + case pix_format_argb64: convert<pixfmt_srgba32, pixfmt_argb64>(&rbuf_tmp, src); break; + case pix_format_abgr64: convert<pixfmt_srgba32, pixfmt_abgr64>(&rbuf_tmp, src); break; + case pix_format_bgra64: convert<pixfmt_srgba32, pixfmt_bgra64>(&rbuf_tmp, src); break; + case pix_format_rgb96: convert<pixfmt_srgba32, pixfmt_rgb96>(&rbuf_tmp, src); break; + case pix_format_bgr96: convert<pixfmt_srgba32, pixfmt_bgr96>(&rbuf_tmp, src); break; + case pix_format_rgba128: convert<pixfmt_srgba32, pixfmt_rgba128>(&rbuf_tmp, src); break; + case pix_format_argb128: convert<pixfmt_srgba32, pixfmt_argb128>(&rbuf_tmp, src); break; + case pix_format_abgr128: convert<pixfmt_srgba32, pixfmt_abgr128>(&rbuf_tmp, src); break; + case pix_format_bgra128: convert<pixfmt_srgba32, pixfmt_bgra128>(&rbuf_tmp, src); break; + } + break; + + case pix_format_abgr32: + switch(m_format) + { + default: break; + case pix_format_sgray8: convert<pixfmt_sabgr32, pixfmt_sgray8>(&rbuf_tmp, src); break; + case pix_format_gray8: convert<pixfmt_sabgr32, pixfmt_gray8>(&rbuf_tmp, src); break; + case pix_format_gray16: convert<pixfmt_sabgr32, pixfmt_gray16>(&rbuf_tmp, src); break; + case pix_format_gray32: convert<pixfmt_sabgr32, pixfmt_gray32>(&rbuf_tmp, src); break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_abgr32()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_abgr32()); break; + case pix_format_srgb24: convert<pixfmt_sabgr32, pixfmt_srgb24>(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert<pixfmt_sabgr32, pixfmt_sbgr24>(&rbuf_tmp, src); break; + case pix_format_rgb24: convert<pixfmt_sabgr32, pixfmt_rgb24>(&rbuf_tmp, src); break; + case pix_format_bgr24: convert<pixfmt_sabgr32, pixfmt_bgr24>(&rbuf_tmp, src); break; + case pix_format_srgba32: convert<pixfmt_sabgr32, pixfmt_srgba32>(&rbuf_tmp, src); break; + case pix_format_sargb32: convert<pixfmt_sabgr32, pixfmt_sargb32>(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert<pixfmt_sabgr32, pixfmt_sabgr32>(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert<pixfmt_sabgr32, pixfmt_sbgra32>(&rbuf_tmp, src); break; + case pix_format_rgba32: convert<pixfmt_sabgr32, pixfmt_rgba32>(&rbuf_tmp, src); break; + case pix_format_argb32: convert<pixfmt_sabgr32, pixfmt_argb32>(&rbuf_tmp, src); break; + case pix_format_abgr32: convert<pixfmt_sabgr32, pixfmt_abgr32>(&rbuf_tmp, src); break; + case pix_format_bgra32: convert<pixfmt_sabgr32, pixfmt_bgra32>(&rbuf_tmp, src); break; + case pix_format_rgb48: convert<pixfmt_sabgr32, pixfmt_rgb48>(&rbuf_tmp, src); break; + case pix_format_bgr48: convert<pixfmt_sabgr32, pixfmt_bgr48>(&rbuf_tmp, src); break; + case pix_format_rgba64: convert<pixfmt_sabgr32, pixfmt_rgba64>(&rbuf_tmp, src); break; + case pix_format_argb64: convert<pixfmt_sabgr32, pixfmt_argb64>(&rbuf_tmp, src); break; + case pix_format_abgr64: convert<pixfmt_sabgr32, pixfmt_abgr64>(&rbuf_tmp, src); break; + case pix_format_bgra64: convert<pixfmt_sabgr32, pixfmt_bgra64>(&rbuf_tmp, src); break; + case pix_format_rgb96: convert<pixfmt_sabgr32, pixfmt_rgb96>(&rbuf_tmp, src); break; + case pix_format_bgr96: convert<pixfmt_sabgr32, pixfmt_bgr96>(&rbuf_tmp, src); break; + case pix_format_rgba128: convert<pixfmt_sabgr32, pixfmt_rgba128>(&rbuf_tmp, src); break; + case pix_format_argb128: convert<pixfmt_sabgr32, pixfmt_argb128>(&rbuf_tmp, src); break; + case pix_format_abgr128: convert<pixfmt_sabgr32, pixfmt_abgr128>(&rbuf_tmp, src); break; + case pix_format_bgra128: convert<pixfmt_sabgr32, pixfmt_bgra128>(&rbuf_tmp, src); break; + } + break; + + case pix_format_argb32: + switch(m_format) + { + default: break; + case pix_format_sgray8: convert<pixfmt_sargb32, pixfmt_sgray8>(&rbuf_tmp, src); break; + case pix_format_gray8: convert<pixfmt_sargb32, pixfmt_gray8>(&rbuf_tmp, src); break; + case pix_format_gray16: convert<pixfmt_sargb32, pixfmt_gray16>(&rbuf_tmp, src); break; + case pix_format_gray32: convert<pixfmt_sargb32, pixfmt_gray32>(&rbuf_tmp, src); break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_argb32()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_argb32()); break; + case pix_format_srgb24: convert<pixfmt_sargb32, pixfmt_srgb24>(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert<pixfmt_sargb32, pixfmt_sbgr24>(&rbuf_tmp, src); break; + case pix_format_rgb24: convert<pixfmt_sargb32, pixfmt_rgb24>(&rbuf_tmp, src); break; + case pix_format_bgr24: convert<pixfmt_sargb32, pixfmt_bgr24>(&rbuf_tmp, src); break; + case pix_format_srgba32: convert<pixfmt_sargb32, pixfmt_srgba32>(&rbuf_tmp, src); break; + case pix_format_sargb32: convert<pixfmt_sargb32, pixfmt_sargb32>(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert<pixfmt_sargb32, pixfmt_sabgr32>(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert<pixfmt_sargb32, pixfmt_sbgra32>(&rbuf_tmp, src); break; + case pix_format_rgba32: convert<pixfmt_sargb32, pixfmt_rgba32>(&rbuf_tmp, src); break; + case pix_format_argb32: convert<pixfmt_sargb32, pixfmt_argb32>(&rbuf_tmp, src); break; + case pix_format_abgr32: convert<pixfmt_sargb32, pixfmt_abgr32>(&rbuf_tmp, src); break; + case pix_format_bgra32: convert<pixfmt_sargb32, pixfmt_bgra32>(&rbuf_tmp, src); break; + case pix_format_rgb48: convert<pixfmt_sargb32, pixfmt_rgb48>(&rbuf_tmp, src); break; + case pix_format_bgr48: convert<pixfmt_sargb32, pixfmt_bgr48>(&rbuf_tmp, src); break; + case pix_format_rgba64: convert<pixfmt_sargb32, pixfmt_rgba64>(&rbuf_tmp, src); break; + case pix_format_argb64: convert<pixfmt_sargb32, pixfmt_argb64>(&rbuf_tmp, src); break; + case pix_format_abgr64: convert<pixfmt_sargb32, pixfmt_abgr64>(&rbuf_tmp, src); break; + case pix_format_bgra64: convert<pixfmt_sargb32, pixfmt_bgra64>(&rbuf_tmp, src); break; + case pix_format_rgb96: convert<pixfmt_sargb32, pixfmt_rgb96>(&rbuf_tmp, src); break; + case pix_format_bgr96: convert<pixfmt_sargb32, pixfmt_bgr96>(&rbuf_tmp, src); break; + case pix_format_rgba128: convert<pixfmt_sargb32, pixfmt_rgba128>(&rbuf_tmp, src); break; + case pix_format_argb128: convert<pixfmt_sargb32, pixfmt_argb128>(&rbuf_tmp, src); break; + case pix_format_abgr128: convert<pixfmt_sargb32, pixfmt_abgr128>(&rbuf_tmp, src); break; + case pix_format_bgra128: convert<pixfmt_sargb32, pixfmt_bgra128>(&rbuf_tmp, src); break; + } + break; + + case pix_format_bgra32: + switch(m_format) + { + default: break; + case pix_format_sgray8: convert<pixfmt_sbgra32, pixfmt_sgray8>(&rbuf_tmp, src); break; + case pix_format_gray8: convert<pixfmt_sbgra32, pixfmt_gray8>(&rbuf_tmp, src); break; + case pix_format_gray16: convert<pixfmt_sbgra32, pixfmt_gray16>(&rbuf_tmp, src); break; + case pix_format_gray32: convert<pixfmt_sbgra32, pixfmt_gray32>(&rbuf_tmp, src); break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_bgra32()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_bgra32()); break; + case pix_format_srgb24: convert<pixfmt_sbgra32, pixfmt_srgb24>(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert<pixfmt_sbgra32, pixfmt_sbgr24>(&rbuf_tmp, src); break; + case pix_format_rgb24: convert<pixfmt_sbgra32, pixfmt_rgb24>(&rbuf_tmp, src); break; + case pix_format_bgr24: convert<pixfmt_sbgra32, pixfmt_bgr24>(&rbuf_tmp, src); break; + case pix_format_srgba32: convert<pixfmt_sbgra32, pixfmt_srgba32>(&rbuf_tmp, src); break; + case pix_format_sargb32: convert<pixfmt_sbgra32, pixfmt_sargb32>(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert<pixfmt_sbgra32, pixfmt_sabgr32>(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert<pixfmt_sbgra32, pixfmt_sbgra32>(&rbuf_tmp, src); break; + case pix_format_rgba32: convert<pixfmt_sbgra32, pixfmt_rgba32>(&rbuf_tmp, src); break; + case pix_format_argb32: convert<pixfmt_sbgra32, pixfmt_argb32>(&rbuf_tmp, src); break; + case pix_format_abgr32: convert<pixfmt_sbgra32, pixfmt_abgr32>(&rbuf_tmp, src); break; + case pix_format_bgra32: convert<pixfmt_sbgra32, pixfmt_bgra32>(&rbuf_tmp, src); break; + case pix_format_rgb48: convert<pixfmt_sbgra32, pixfmt_rgb48>(&rbuf_tmp, src); break; + case pix_format_bgr48: convert<pixfmt_sbgra32, pixfmt_bgr48>(&rbuf_tmp, src); break; + case pix_format_rgba64: convert<pixfmt_sbgra32, pixfmt_rgba64>(&rbuf_tmp, src); break; + case pix_format_argb64: convert<pixfmt_sbgra32, pixfmt_argb64>(&rbuf_tmp, src); break; + case pix_format_abgr64: convert<pixfmt_sbgra32, pixfmt_abgr64>(&rbuf_tmp, src); break; + case pix_format_bgra64: convert<pixfmt_sbgra32, pixfmt_bgra64>(&rbuf_tmp, src); break; + case pix_format_rgb96: convert<pixfmt_sbgra32, pixfmt_rgb96>(&rbuf_tmp, src); break; + case pix_format_bgr96: convert<pixfmt_sbgra32, pixfmt_bgr96>(&rbuf_tmp, src); break; + case pix_format_rgba128: convert<pixfmt_sbgra32, pixfmt_rgba128>(&rbuf_tmp, src); break; + case pix_format_argb128: convert<pixfmt_sbgra32, pixfmt_argb128>(&rbuf_tmp, src); break; + case pix_format_abgr128: convert<pixfmt_sbgra32, pixfmt_abgr128>(&rbuf_tmp, src); break; + case pix_format_bgra128: convert<pixfmt_sbgra32, pixfmt_bgra128>(&rbuf_tmp, src); break; + } + break; + } + + m_ximg_window->data = (char*)buf_tmp; + XPutImage(m_display, + m_window, + m_gc, + m_ximg_window, + 0, 0, 0, 0, + src->width(), + src->height()); + + delete [] buf_tmp; + } + } + + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(format, flip_y)), + m_format(format), + m_bpp(m_specific->m_bpp), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y), + m_initial_width(10), + m_initial_height(10) + { + std::strcpy(m_caption, "AGG Application"); + } + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + std::strcpy(m_caption, cap); + if(m_specific->m_initialized) + { + m_specific->caption(cap); + } + } + + + //------------------------------------------------------------------------ + enum xevent_mask_e + { + xevent_mask = + PointerMotionMask| + ButtonPressMask| + ButtonReleaseMask| + ExposureMask| + KeyPressMask| + StructureNotifyMask + }; + + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, unsigned flags) + { + m_window_flags = flags; + + m_specific->m_display = XOpenDisplay(NULL); + if(m_specific->m_display == 0) + { + std::fprintf(stderr, "Unable to open DISPLAY!\n"); + return false; + } + + m_specific->m_screen = XDefaultScreen(m_specific->m_display); + m_specific->m_depth = XDefaultDepth(m_specific->m_display, + m_specific->m_screen); + m_specific->m_visual = XDefaultVisual(m_specific->m_display, + m_specific->m_screen); + unsigned long r_mask = m_specific->m_visual->red_mask; + unsigned long g_mask = m_specific->m_visual->green_mask; + unsigned long b_mask = m_specific->m_visual->blue_mask; + +//std::printf("depth=%d, red=%08x, green=%08x, blue=%08x\n", +// m_specific->m_depth, +// m_specific->m_visual->red_mask, +// m_specific->m_visual->green_mask, +// m_specific->m_visual->blue_mask); + + +// // NOT COMPLETED YET! +// // Try to find an appropriate Visual if the default doesn't fit. +// if(m_specific->m_depth < 15 || +// r_mask == 0 || g_mask == 0 || b_mask == 0) +// { +// +// // This is an attempt to find an appropriate Visual if +// // the default one doesn't match the minumum requirements +// static int depth[] = { 32, 24, 16, 15 }; +// int i; +// for(int i = 0; i < 4; i++) +// { +// XVisualInfo vi; +// if(XMatchVisualInfo(m_specific->m_display, +// m_specific->m_screen, +// depth[i], +// TrueColor, +// &vi)) +// { +// // std::printf("TrueColor depth=%d, red=%08x, green=%08x, blue=%08x, bits=%d\n", +// // vi.depth, +// // vi.visual->red_mask, +// // vi.visual->green_mask, +// // vi.visual->blue_mask, +// // vi.bits_per_rgb); +// m_specific->m_depth = vi.depth; +// m_specific->m_visual = vi.visual; +// r_mask = m_specific->m_visual->red_mask; +// g_mask = m_specific->m_visual->green_mask; +// b_mask = m_specific->m_visual->blue_mask; +// break; +// } +// if(XMatchVisualInfo(m_specific->m_display, +// m_specific->m_screen, +// depth[i], +// DirectColor, +// &vi)) +// { +// // std::printf("DirectColor depth=%d, red=%08x, green=%08x, blue=%08x, bits=%d\n", +// // vi.depth, +// // vi.visual->red_mask, +// // vi.visual->green_mask, +// // vi.visual->blue_mask, +// // vi.bits_per_rgb); +// m_specific->m_depth = vi.depth; +// m_specific->m_visual = vi.visual; +// r_mask = m_specific->m_visual->red_mask; +// g_mask = m_specific->m_visual->green_mask; +// b_mask = m_specific->m_visual->blue_mask; +// break; +// } +// } +// } + + if(m_specific->m_depth < 15 || + r_mask == 0 || g_mask == 0 || b_mask == 0) + { + std::fprintf(stderr, + "There's no Visual compatible with minimal AGG requirements:\n" + "At least 15-bit color depth and True- or DirectColor class.\n\n"); + XCloseDisplay(m_specific->m_display); + return false; + } + + int t = 1; + int hw_byte_order = LSBFirst; + if(*(char*)&t == 0) hw_byte_order = MSBFirst; + + // Perceive SYS-format by mask + switch(m_specific->m_depth) + { + case 15: + m_specific->m_sys_bpp = 16; + if(r_mask == 0x7C00 && g_mask == 0x3E0 && b_mask == 0x1F) + { + m_specific->m_sys_format = pix_format_rgb555; + m_specific->m_byte_order = hw_byte_order; + } + break; + + case 16: + m_specific->m_sys_bpp = 16; + if(r_mask == 0xF800 && g_mask == 0x7E0 && b_mask == 0x1F) + { + m_specific->m_sys_format = pix_format_rgb565; + m_specific->m_byte_order = hw_byte_order; + } + break; + + case 24: + case 32: + m_specific->m_sys_bpp = 32; + if(g_mask == 0xFF00) + { + if(r_mask == 0xFF && b_mask == 0xFF0000) + { + switch(m_specific->m_format) + { + case pix_format_rgba32: + m_specific->m_sys_format = pix_format_rgba32; + m_specific->m_byte_order = LSBFirst; + break; + + case pix_format_abgr32: + m_specific->m_sys_format = pix_format_abgr32; + m_specific->m_byte_order = MSBFirst; + break; + + default: + m_specific->m_byte_order = hw_byte_order; + m_specific->m_sys_format = + (hw_byte_order == LSBFirst) ? + pix_format_rgba32 : + pix_format_abgr32; + break; + } + } + + if(r_mask == 0xFF0000 && b_mask == 0xFF) + { + switch(m_specific->m_format) + { + case pix_format_argb32: + m_specific->m_sys_format = pix_format_argb32; + m_specific->m_byte_order = MSBFirst; + break; + + case pix_format_bgra32: + m_specific->m_sys_format = pix_format_bgra32; + m_specific->m_byte_order = LSBFirst; + break; + + default: + m_specific->m_byte_order = hw_byte_order; + m_specific->m_sys_format = + (hw_byte_order == MSBFirst) ? + pix_format_argb32 : + pix_format_bgra32; + break; + } + } + } + break; + } + + if(m_specific->m_sys_format == pix_format_undefined) + { + std::fprintf(stderr, + "RGB masks are not compatible with AGG pixel formats:\n" + "R=%08lx, R=%08lx, B=%08lx\n", r_mask, g_mask, b_mask); + XCloseDisplay(m_specific->m_display); + return false; + } + + + + std::memset(&m_specific->m_window_attributes, + 0, + sizeof(m_specific->m_window_attributes)); + + m_specific->m_window_attributes.border_pixel = + XBlackPixel(m_specific->m_display, m_specific->m_screen); + + m_specific->m_window_attributes.background_pixel = + XWhitePixel(m_specific->m_display, m_specific->m_screen); + + m_specific->m_window_attributes.override_redirect = 0; + + unsigned long window_mask = CWBackPixel | CWBorderPixel; + + m_specific->m_window = + XCreateWindow(m_specific->m_display, + XDefaultRootWindow(m_specific->m_display), + 0, 0, + width, + height, + 0, + m_specific->m_depth, + InputOutput, + CopyFromParent, + window_mask, + &m_specific->m_window_attributes); + + + m_specific->m_gc = XCreateGC(m_specific->m_display, + m_specific->m_window, + 0, 0); + m_specific->m_buf_window = + new unsigned char[width * height * (m_bpp / 8)]; + + std::memset(m_specific->m_buf_window, 255, width * height * (m_bpp / 8)); + + m_rbuf_window.attach(m_specific->m_buf_window, + width, + height, + m_flip_y ? -width * (m_bpp / 8) : width * (m_bpp / 8)); + + m_specific->m_ximg_window = + XCreateImage(m_specific->m_display, + m_specific->m_visual, //CopyFromParent, + m_specific->m_depth, + ZPixmap, + 0, + (char*)m_specific->m_buf_window, + width, + height, + m_specific->m_sys_bpp, + width * (m_specific->m_sys_bpp / 8)); + m_specific->m_ximg_window->byte_order = m_specific->m_byte_order; + + m_specific->caption(m_caption); + m_initial_width = width; + m_initial_height = height; + + if(!m_specific->m_initialized) + { + on_init(); + m_specific->m_initialized = true; + } + + trans_affine_resizing(width, height); + on_resize(width, height); + m_specific->m_update_flag = true; + + XSizeHints *hints = XAllocSizeHints(); + if(hints) + { + if(flags & window_resize) + { + hints->min_width = 32; + hints->min_height = 32; + hints->max_width = 4096; + hints->max_height = 4096; + } + else + { + hints->min_width = width; + hints->min_height = height; + hints->max_width = width; + hints->max_height = height; + } + hints->flags = PMaxSize | PMinSize; + + XSetWMNormalHints(m_specific->m_display, + m_specific->m_window, + hints); + + XFree(hints); + } + + + XMapWindow(m_specific->m_display, + m_specific->m_window); + + XSelectInput(m_specific->m_display, + m_specific->m_window, + xevent_mask); + + + m_specific->m_close_atom = XInternAtom(m_specific->m_display, + "WM_DELETE_WINDOW", + false); + + XSetWMProtocols(m_specific->m_display, + m_specific->m_window, + &m_specific->m_close_atom, + 1); + + return true; + } + + + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + m_specific->put_image(&m_rbuf_window); + + // When m_wait_mode is true we can discard all the events + // came while the image is being drawn. In this case + // the X server does not accumulate mouse motion events. + // When m_wait_mode is false, i.e. we have some idle drawing + // we cannot afford to miss any events + XSync(m_specific->m_display, m_wait_mode); + } + + + //------------------------------------------------------------------------ + int platform_support::run() + { + XFlush(m_specific->m_display); + + bool quit = false; + unsigned flags; + int cur_x; + int cur_y; + + while(!quit) + { + if(m_specific->m_update_flag) + { + on_draw(); + update_window(); + m_specific->m_update_flag = false; + } + + if(!m_wait_mode) + { + if(XPending(m_specific->m_display) == 0) + { + on_idle(); + continue; + } + } + + XEvent x_event; + XNextEvent(m_specific->m_display, &x_event); + + // In the Idle mode discard all intermediate MotionNotify events + if(!m_wait_mode && x_event.type == MotionNotify) + { + XEvent te = x_event; + for(;;) + { + if(XPending(m_specific->m_display) == 0) break; + XNextEvent(m_specific->m_display, &te); + if(te.type != MotionNotify) break; + } + x_event = te; + } + + switch(x_event.type) + { + case ConfigureNotify: + { + if(x_event.xconfigure.width != int(m_rbuf_window.width()) || + x_event.xconfigure.height != int(m_rbuf_window.height())) + { + int width = x_event.xconfigure.width; + int height = x_event.xconfigure.height; + + delete [] m_specific->m_buf_window; + m_specific->m_ximg_window->data = 0; + XDestroyImage(m_specific->m_ximg_window); + + m_specific->m_buf_window = + new unsigned char[width * height * (m_bpp / 8)]; + + m_rbuf_window.attach(m_specific->m_buf_window, + width, + height, + m_flip_y ? + -width * (m_bpp / 8) : + width * (m_bpp / 8)); + + m_specific->m_ximg_window = + XCreateImage(m_specific->m_display, + m_specific->m_visual, //CopyFromParent, + m_specific->m_depth, + ZPixmap, + 0, + (char*)m_specific->m_buf_window, + width, + height, + m_specific->m_sys_bpp, + width * (m_specific->m_sys_bpp / 8)); + m_specific->m_ximg_window->byte_order = m_specific->m_byte_order; + + trans_affine_resizing(width, height); + on_resize(width, height); + on_draw(); + update_window(); + } + } + break; + + case Expose: + m_specific->put_image(&m_rbuf_window); + XFlush(m_specific->m_display); + XSync(m_specific->m_display, false); + break; + + case KeyPress: + { + KeySym key = XLookupKeysym(&x_event.xkey, 0); + flags = 0; + if(x_event.xkey.state & Button1Mask) flags |= mouse_left; + if(x_event.xkey.state & Button3Mask) flags |= mouse_right; + if(x_event.xkey.state & ShiftMask) flags |= kbd_shift; + if(x_event.xkey.state & ControlMask) flags |= kbd_ctrl; + + bool left = false; + bool up = false; + bool right = false; + bool down = false; + + switch(m_specific->m_keymap[key & 0xFF]) + { + case key_left: + left = true; + break; + + case key_up: + up = true; + break; + + case key_right: + right = true; + break; + + case key_down: + down = true; + break; + + case key_f2: + copy_window_to_img(max_images - 1); + save_img(max_images - 1, "screenshot"); + break; + } + + if(m_ctrls.on_arrow_keys(left, right, down, up)) + { + on_ctrl_change(); + force_redraw(); + } + else + { + on_key(x_event.xkey.x, + m_flip_y ? + m_rbuf_window.height() - x_event.xkey.y : + x_event.xkey.y, + m_specific->m_keymap[key & 0xFF], + flags); + } + } + break; + + + case ButtonPress: + { + flags = 0; + if(x_event.xbutton.state & ShiftMask) flags |= kbd_shift; + if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl; + if(x_event.xbutton.button == Button1) flags |= mouse_left; + if(x_event.xbutton.button == Button3) flags |= mouse_right; + + cur_x = x_event.xbutton.x; + cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y : + x_event.xbutton.y; + + if(flags & mouse_left) + { + if(m_ctrls.on_mouse_button_down(cur_x, cur_y)) + { + m_ctrls.set_cur(cur_x, cur_y); + on_ctrl_change(); + force_redraw(); + } + else + { + if(m_ctrls.in_rect(cur_x, cur_y)) + { + if(m_ctrls.set_cur(cur_x, cur_y)) + { + on_ctrl_change(); + force_redraw(); + } + } + else + { + on_mouse_button_down(cur_x, cur_y, flags); + } + } + } + if(flags & mouse_right) + { + on_mouse_button_down(cur_x, cur_y, flags); + } + //m_specific->m_wait_mode = m_wait_mode; + //m_wait_mode = true; + } + break; + + + case MotionNotify: + { + flags = 0; + if(x_event.xmotion.state & Button1Mask) flags |= mouse_left; + if(x_event.xmotion.state & Button3Mask) flags |= mouse_right; + if(x_event.xmotion.state & ShiftMask) flags |= kbd_shift; + if(x_event.xmotion.state & ControlMask) flags |= kbd_ctrl; + + cur_x = x_event.xbutton.x; + cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y : + x_event.xbutton.y; + + if(m_ctrls.on_mouse_move(cur_x, cur_y, (flags & mouse_left) != 0)) + { + on_ctrl_change(); + force_redraw(); + } + else + { + if(!m_ctrls.in_rect(cur_x, cur_y)) + { + on_mouse_move(cur_x, cur_y, flags); + } + } + } + break; + + case ButtonRelease: + { + flags = 0; + if(x_event.xbutton.state & ShiftMask) flags |= kbd_shift; + if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl; + if(x_event.xbutton.button == Button1) flags |= mouse_left; + if(x_event.xbutton.button == Button3) flags |= mouse_right; + + cur_x = x_event.xbutton.x; + cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y : + x_event.xbutton.y; + + if(flags & mouse_left) + { + if(m_ctrls.on_mouse_button_up(cur_x, cur_y)) + { + on_ctrl_change(); + force_redraw(); + } + } + if(flags & (mouse_left | mouse_right)) + { + on_mouse_button_up(cur_x, cur_y, flags); + } + } + //m_wait_mode = m_specific->m_wait_mode; + break; + + case ClientMessage: + if((x_event.xclient.format == 32) && + (x_event.xclient.data.l[0] == int(m_specific->m_close_atom))) + { + quit = true; + } + break; + } + } + + + unsigned i = platform_support::max_images; + while(i--) + { + if(m_specific->m_buf_img[i]) + { + delete [] m_specific->m_buf_img[i]; + } + } + + delete [] m_specific->m_buf_window; + m_specific->m_ximg_window->data = 0; + XDestroyImage(m_specific->m_ximg_window); + XFreeGC(m_specific->m_display, m_specific->m_gc); + XDestroyWindow(m_specific->m_display, m_specific->m_window); + XCloseDisplay(m_specific->m_display); + + return 0; + } + + + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const { return ".ppm"; } + + //------------------------------------------------------------------------ + const char* platform_support::full_file_name(const char* file_name) + { + return file_name; + } + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + char buf[1024]; + std::strcpy(buf, file); + int len = std::strlen(buf); + if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0) + { + std::strcat(buf, ".ppm"); + } + + FILE* fd = std::fopen(buf, "rb"); + if(fd == 0) return false; + + if((len = std::fread(buf, 1, 1022, fd)) == 0) + { + fclose(fd); + return false; + } + buf[len] = 0; + + if(buf[0] != 'P' && buf[1] != '6') + { + std::fclose(fd); + return false; + } + + char* ptr = buf + 2; + + while(*ptr && !std::isdigit((unsigned char)(*ptr))) ptr++; + if(*ptr == 0) + { + std::fclose(fd); + return false; + } + + unsigned width = std::atoi(ptr); + if(width == 0 || width > 4096) + { + std::fclose(fd); + return false; + } + while(*ptr && isdigit((unsigned char)(*ptr))) ptr++; + while(*ptr && !isdigit((unsigned char)(*ptr))) ptr++; + if(*ptr == 0) + { + std::fclose(fd); + return false; + } + unsigned height = std::atoi(ptr); + if(height == 0 || height > 4096) + { + std::fclose(fd); + return false; + } + while(*ptr && isdigit((unsigned char)(*ptr))) ptr++; + while(*ptr && !isdigit((unsigned char)(*ptr))) ptr++; + if(std::atoi(ptr) != 255) + { + std::fclose(fd); + return false; + } + while(*ptr && isdigit((unsigned char)(*ptr))) ptr++; + if(*ptr == 0) + { + std::fclose(fd); + return false; + } + ptr++; + std::fseek(fd, long(ptr - buf), SEEK_SET); + + create_img(idx, width, height); + bool ret = true; + + if(m_format == pix_format_rgb24) + { + std::size_t sz = std::fread(m_specific->m_buf_img[idx], 1, width * height * 3, fd); + if (sz != width * height * 3) + ret = false; + } + else + { + unsigned char* buf_img = new unsigned char [width * height * 3]; + rendering_buffer rbuf_img; + rbuf_img.attach(buf_img, + width, + height, + m_flip_y ? + -width * 3 : + width * 3); + + std::size_t sz = std::fread(buf_img, 1, width * height * 3, fd); + if (sz != width * height * 3) + ret = false; + + switch(m_format) + { + case pix_format_sgray8: + convert<pixfmt_sgray8, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_gray8: + convert<pixfmt_gray8, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_gray16: + convert<pixfmt_gray16, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_gray32: + convert<pixfmt_gray32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb555: + color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb555()); + break; + + case pix_format_rgb565: + color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb565()); + break; + + case pix_format_sbgr24: + convert<pixfmt_sbgr24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb24: + convert<pixfmt_rgb24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgr24: + convert<pixfmt_bgr24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_srgba32: + convert<pixfmt_srgba32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_sargb32: + convert<pixfmt_sargb32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_sbgra32: + convert<pixfmt_sbgra32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_sabgr32: + convert<pixfmt_sabgr32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgba32: + convert<pixfmt_rgba32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_argb32: + convert<pixfmt_argb32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgra32: + convert<pixfmt_bgra32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_abgr32: + convert<pixfmt_abgr32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb48: + convert<pixfmt_rgb48, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgr48: + convert<pixfmt_bgr48, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgba64: + convert<pixfmt_rgba64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_argb64: + convert<pixfmt_argb64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgra64: + convert<pixfmt_bgra64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_abgr64: + convert<pixfmt_abgr64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb96: + convert<pixfmt_rgb96, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgr96: + convert<pixfmt_bgr96, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgba128: + convert<pixfmt_rgba128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_argb128: + convert<pixfmt_argb128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgra128: + convert<pixfmt_bgra128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_abgr128: + convert<pixfmt_abgr128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + default: + ret = false; + } + delete [] buf_img; + } + + std::fclose(fd); + return ret; + } + return false; + } + + + + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + if(idx < max_images && rbuf_img(idx).buf()) + { + char buf[1024]; + std::strcpy(buf, file); + int len = std::strlen(buf); + if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0) + { + std::strcat(buf, ".ppm"); + } + + FILE* fd = std::fopen(buf, "wb"); + if(fd == 0) return false; + + unsigned w = rbuf_img(idx).width(); + unsigned h = rbuf_img(idx).height(); + + std::fprintf(fd, "P6\n%d %d\n255\n", w, h); + + unsigned y; + unsigned char* tmp_buf = new unsigned char [w * 3]; + for(y = 0; y < rbuf_img(idx).height(); y++) + { + const unsigned char* src = rbuf_img(idx).row_ptr(m_flip_y ? h - 1 - y : y); + switch(m_format) + { + case pix_format_sgray8: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sgray8>()); + break; + + case pix_format_gray8: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray8>()); + break; + + case pix_format_gray16: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray16>()); + break; + + case pix_format_gray32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray32>()); + break; + + default: break; + case pix_format_rgb555: + color_conv_row(tmp_buf, src, w, color_conv_rgb555_to_rgb24()); + break; + + case pix_format_rgb565: + color_conv_row(tmp_buf, src, w, color_conv_rgb565_to_rgb24()); + break; + + case pix_format_sbgr24: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sbgr24>()); + break; + + case pix_format_srgb24: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_srgb24>()); + break; + + case pix_format_bgr24: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr24>()); + break; + + case pix_format_rgb24: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb24>()); + break; + + case pix_format_srgba32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_srgba32>()); + break; + + case pix_format_sargb32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sargb32>()); + break; + + case pix_format_sbgra32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sbgra32>()); + break; + + case pix_format_sabgr32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sabgr32>()); + break; + + case pix_format_rgba32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba32>()); + break; + + case pix_format_argb32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb32>()); + break; + + case pix_format_bgra32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra32>()); + break; + + case pix_format_abgr32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr32>()); + break; + + case pix_format_bgr48: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr48>()); + break; + + case pix_format_rgb48: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb48>()); + break; + + case pix_format_rgba64: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba64>()); + break; + + case pix_format_argb64: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb64>()); + break; + + case pix_format_bgra64: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra64>()); + break; + + case pix_format_abgr64: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr64>()); + break; + + case pix_format_bgr96: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr96>()); + break; + + case pix_format_rgb96: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb96>()); + break; + + case pix_format_rgba128: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba128>()); + break; + + case pix_format_argb128: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb128>()); + break; + + case pix_format_bgra128: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra128>()); + break; + + case pix_format_abgr128: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr128>()); + break; + } + std::fwrite(tmp_buf, 1, w * 3, fd); + } + delete [] tmp_buf; + std::fclose(fd); + return true; + } + return false; + } + + + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) + { + if(idx < max_images) + { + if(width == 0) width = rbuf_window().width(); + if(height == 0) height = rbuf_window().height(); + delete [] m_specific->m_buf_img[idx]; + m_specific->m_buf_img[idx] = + new unsigned char[width * height * (m_bpp / 8)]; + + m_rbuf_img[idx].attach(m_specific->m_buf_img[idx], + width, + height, + m_flip_y ? + -width * (m_bpp / 8) : + width * (m_bpp / 8)); + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + m_specific->m_update_flag = true; + } + + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + std::fprintf(stderr, "%s\n", msg); + } + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + m_specific->m_sw_start = clock(); + } + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + std::clock_t stop = std::clock(); + return double(stop - m_specific->m_sw_start) * 1000.0 / CLOCKS_PER_SEC; + } + + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} + + + +} + + +int agg_main(int argc, char* argv[]); + + +int main(int argc, char* argv[]) +{ + return agg_main(argc, argv); +} + + + + + + diff --git a/src/platform/mac/Makefile.am b/src/platform/mac/Makefile.am new file mode 100644 index 0000000..6f1b860 --- /dev/null +++ b/src/platform/mac/Makefile.am @@ -0,0 +1,11 @@ +if ENABLE_OSX +lib_LTLIBRARIES = libaggplatformmac.la +libaggplatformmac_la_LDFLAGS=-version-info @AGG_LIB_VERSION@ +libaggplatformmac_la_SOURCES=agg_mac_pmap.cpp \ + agg_platform_support.cpp + +libaggplatformmac_la_CXXFLAGS = -I$(top_srcdir)/include @OSX_CFLAGS@ +libaggplatformmac_la_LIBADD = @OSX_LIBS@ $(top_builddir)/src/libagg.la + + +endif diff --git a/src/platform/mac/agg_mac_pmap.cpp b/src/platform/mac/agg_mac_pmap.cpp new file mode 100644 index 0000000..dbc6c46 --- /dev/null +++ b/src/platform/mac/agg_mac_pmap.cpp @@ -0,0 +1,298 @@ +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +// Contact: mcseemagg@yahoo.com +// baer@karto.baug.ethz.ch +//---------------------------------------------------------------------------- +// +// class pixel_map +// +//---------------------------------------------------------------------------- + +#include <cstring> +#include <Carbon.h> +#include <QuickTimeComponents.h> +#include <ImageCompression.h> +#include "platform/mac/agg_mac_pmap.h" +#include "agg_basics.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + pixel_map::~pixel_map() + { + destroy(); + } + + + //------------------------------------------------------------------------ + pixel_map::pixel_map() : + m_pmap(0), + m_buf(0), + m_bpp(0), + m_img_size(0) + + { + } + + + //------------------------------------------------------------------------ + void pixel_map::destroy() + { + delete[] m_buf; + m_buf = NULL; + if (m_pmap != nil) + { + DisposeGWorld(m_pmap); + m_pmap = nil; + } + } + + + //------------------------------------------------------------------------ + void pixel_map::create(unsigned width, + unsigned height, + org_e org, + unsigned clear_val) + { + destroy(); + if(width == 0) width = 1; + if(height == 0) height = 1; + m_bpp = org; + + Rect r; + int row_bytes = calc_row_len (width, m_bpp); + MacSetRect(&r, 0, 0, width, height); + m_buf = new unsigned char[m_img_size = row_bytes * height]; + // The Quicktime version for creating GWorlds is more flexible than the classical function. + QTNewGWorldFromPtr (&m_pmap, m_bpp, &r, nil, nil, 0, m_buf, row_bytes); + + // create_gray_scale_palette(m_pmap); I didn't care about gray scale palettes so far. + if(clear_val <= 255) + { + std::memset(m_buf, clear_val, m_img_size); + } + } + + + + //------------------------------------------------------------------------ + void pixel_map::clear(unsigned clear_val) + { + if(m_buf) std::memset(m_buf, clear_val, m_img_size); + } + + + //static + //This function is just copied from the Win32 plattform support. + //Is also seems to be appropriate for MacOS as well, but it is not + //thouroughly tested so far. + //------------------------------------------------------------------------ + + unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel) + { + unsigned n = width; + unsigned k; + + switch(bits_per_pixel) + { + case 1: k = n; + n = n >> 3; + if(k & 7) n++; + break; + + case 4: k = n; + n = n >> 1; + if(k & 3) n++; + break; + + case 8: + break; + + case 16: n = n << 1; + break; + + case 24: n = (n << 1) + n; + break; + + case 32: n = n << 2; + break; + + default: n = 0; + break; + } + return ((n + 3) >> 2) << 2; + } + + + + + //------------------------------------------------------------------------ + void pixel_map::draw(WindowRef window, const Rect *device_rect, const Rect *pmap_rect) const + { + if(m_pmap == nil || m_buf == NULL) return; + + PixMapHandle pm = GetGWorldPixMap (m_pmap); + CGrafPtr port = GetWindowPort (window); + Rect dest_rect; + + // Again, I used the Quicktime version. + // Good old 'CopyBits' does better interpolation when scaling + // but does not support all pixel depths. + MacSetRect (&dest_rect, 0, 0, this->width(), this->height()); + ImageDescriptionHandle image_description; + MakeImageDescriptionForPixMap (pm, &image_description); + if (image_description != nil) + { + DecompressImage (GetPixBaseAddr (pm), image_description, GetPortPixMap (port), nil, &dest_rect, ditherCopy, nil); + DisposeHandle ((Handle) image_description); + } + } + + + //------------------------------------------------------------------------ + void pixel_map::draw(WindowRef window, int x, int y, double scale) const + { + if(m_pmap == nil || m_buf == NULL) return; + unsigned width = (unsigned)(this->width() * scale); + unsigned height = (unsigned)(this->height() * scale); + Rect rect; + SetRect (&rect, x, y, x + width, y + height); + draw(window, &rect); + } + + + + //------------------------------------------------------------------------ + void pixel_map::blend(WindowRef window, const Rect *device_rect, const Rect *bmp_rect) const + { + draw (window, device_rect, bmp_rect); // currently just mapped to drawing method + } + + + //------------------------------------------------------------------------ + void pixel_map::blend(WindowRef window, int x, int y, double scale) const + { + draw(window, x, y, scale); // currently just mapped to drawing method + } + + + // I let Quicktime handle image import since it supports most popular + // image formats such as: + // *.psd, *.bmp, *.tif, *.png, *.jpg, *.gif, *.pct, *.pcx + //------------------------------------------------------------------------ + bool pixel_map::load_from_qt(const char *filename) + { + FSSpec fss; + OSErr err; + + // get file specification to application directory + err = HGetVol(nil, &fss.vRefNum, &fss.parID); + if (err == noErr) + { + CopyCStringToPascal(filename, fss.name); + GraphicsImportComponent gi; + err = GetGraphicsImporterForFile (&fss, &gi); + if (err == noErr) + { + ImageDescriptionHandle desc; + GraphicsImportGetImageDescription(gi, &desc); +// For simplicity, all images are currently converted to 32 bit. + // create an empty pixelmap + short depth = 32; + create ((**desc).width, (**desc).height, (org_e)depth, 0xff); + DisposeHandle ((Handle)desc); + // let Quicktime draw to pixelmap + GraphicsImportSetGWorld(gi, m_pmap, nil); + GraphicsImportDraw(gi); +// Well, this is a hack. The graphics importer sets the alpha channel of the pixelmap to 0x00 +// for imported images without alpha channel but this would cause agg to draw an invisible image. + // set alpha channel to 0xff + unsigned char * buf = m_buf; + for (unsigned int size = 0; size < m_img_size; size += 4) + { + *buf = 0xff; + buf += 4; + } + } + } + return err == noErr; + } + + + + //------------------------------------------------------------------------ + bool pixel_map::save_as_qt(const char *filename) const + { + FSSpec fss; + OSErr err; + + // get file specification to application directory + err = HGetVol(nil, &fss.vRefNum, &fss.parID); + if (err == noErr) + { + GraphicsExportComponent ge; + CopyCStringToPascal(filename, fss.name); + // I decided to use PNG as output image file type. + // There are a number of other available formats. + // Should I check the file suffix to choose the image file format? + err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePNG, &ge); + if (err == noErr) + { + err = GraphicsExportSetInputGWorld(ge, m_pmap); + if (err == noErr) + { + err = GraphicsExportSetOutputFile (ge, &fss); + if (err == noErr) + { + GraphicsExportDoExport(ge, nil); + } + } + CloseComponent(ge); + } + } + + return err == noErr; + } + + //------------------------------------------------------------------------ + unsigned char* pixel_map::buf() + { + return m_buf; + } + + //------------------------------------------------------------------------ + unsigned pixel_map::width() const + { + if(m_pmap == nil) return 0; + PixMapHandle pm = GetGWorldPixMap (m_pmap); + Rect bounds; + GetPixBounds (pm, &bounds); + return bounds.right - bounds.left; + } + + //------------------------------------------------------------------------ + unsigned pixel_map::height() const + { + if(m_pmap == nil) return 0; + PixMapHandle pm = GetGWorldPixMap (m_pmap); + Rect bounds; + GetPixBounds (pm, &bounds); + return bounds.bottom - bounds.top; + } + + //------------------------------------------------------------------------ + int pixel_map::row_bytes() const + { + if(m_pmap == nil) return 0; + PixMapHandle pm = GetGWorldPixMap (m_pmap); + return calc_row_len(width(), GetPixDepth(pm)); + } + + + +} + + + diff --git a/src/platform/mac/agg_platform_support.cpp b/src/platform/mac/agg_platform_support.cpp new file mode 100644 index 0000000..a1c2a00 --- /dev/null +++ b/src/platform/mac/agg_platform_support.cpp @@ -0,0 +1,1053 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) +// Copyright (C) 2003 Hansruedi Baer (MacOS support) +// +// 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 +// baer@karto.baug.eth.ch +//---------------------------------------------------------------------------- +// +// class platform_support +// +//---------------------------------------------------------------------------- +// +// Note: +// I tried to retain the original structure for the Win32 platform as far +// as possible. Currently, not all features are implemented but the examples +// should work properly. +// HB +//---------------------------------------------------------------------------- + +#include <Carbon.h> +#if defined(__MWERKS__) +#include "console.h" +#endif +#include <cstring> +#include <unistd.h> +#include "platform/agg_platform_support.h" +#include "platform/mac/agg_mac_pmap.h" +#include "util/agg_color_conv_rgb8.h" + + +namespace agg +{ + +pascal OSStatus DoWindowClose (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoWindowDrawContent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoAppQuit (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoMouseDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoMouseDragged (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoKeyDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoKeyUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal void DoPeriodicTask (EventLoopTimerRef theTimer, void* userData); + + + //------------------------------------------------------------------------ + class platform_specific + { + public: + platform_specific(pix_format_e format, bool flip_y); + + void create_pmap(unsigned width, unsigned height, + rendering_buffer* wnd); + + void display_pmap(WindowRef window, const rendering_buffer* src); + bool load_pmap(const char* fn, unsigned idx, + rendering_buffer* dst); + + bool save_pmap(const char* fn, unsigned idx, + const rendering_buffer* src); + + unsigned translate(unsigned keycode); + + pix_format_e m_format; + pix_format_e m_sys_format; + bool m_flip_y; + unsigned m_bpp; + unsigned m_sys_bpp; + WindowRef m_window; + pixel_map m_pmap_window; + pixel_map m_pmap_img[platform_support::max_images]; + unsigned m_keymap[256]; + unsigned m_last_translated_key; + int m_cur_x; + int m_cur_y; + unsigned m_input_flags; + bool m_redraw_flag; + UnsignedWide m_sw_freq; + UnsignedWide m_sw_start; + }; + + + //------------------------------------------------------------------------ + platform_specific::platform_specific(pix_format_e format, bool flip_y) : + m_format(format), + m_sys_format(pix_format_undefined), + m_flip_y(flip_y), + m_bpp(0), + m_sys_bpp(0), + m_window(nil), + m_last_translated_key(0), + m_cur_x(0), + m_cur_y(0), + m_input_flags(0), + m_redraw_flag(true) + { + std::memset(m_keymap, 0, sizeof(m_keymap)); + + //Keyboard input is not yet fully supported nor tested + //m_keymap[VK_PAUSE] = key_pause; + m_keymap[kClearCharCode] = key_clear; + + //m_keymap[VK_NUMPAD0] = key_kp0; + //m_keymap[VK_NUMPAD1] = key_kp1; + //m_keymap[VK_NUMPAD2] = key_kp2; + //m_keymap[VK_NUMPAD3] = key_kp3; + //m_keymap[VK_NUMPAD4] = key_kp4; + //m_keymap[VK_NUMPAD5] = key_kp5; + //m_keymap[VK_NUMPAD6] = key_kp6; + //m_keymap[VK_NUMPAD7] = key_kp7; + //m_keymap[VK_NUMPAD8] = key_kp8; + //m_keymap[VK_NUMPAD9] = key_kp9; + //m_keymap[VK_DECIMAL] = key_kp_period; + //m_keymap[VK_DIVIDE] = key_kp_divide; + //m_keymap[VK_MULTIPLY] = key_kp_multiply; + //m_keymap[VK_SUBTRACT] = key_kp_minus; + //m_keymap[VK_ADD] = key_kp_plus; + + m_keymap[kUpArrowCharCode] = key_up; + m_keymap[kDownArrowCharCode] = key_down; + m_keymap[kRightArrowCharCode] = key_right; + m_keymap[kLeftArrowCharCode] = key_left; + //m_keymap[VK_INSERT] = key_insert; + m_keymap[kDeleteCharCode] = key_delete; + m_keymap[kHomeCharCode] = key_home; + m_keymap[kEndCharCode] = key_end; + m_keymap[kPageUpCharCode] = key_page_up; + m_keymap[kPageDownCharCode] = key_page_down; + + //m_keymap[VK_F1] = key_f1; + //m_keymap[VK_F2] = key_f2; + //m_keymap[VK_F3] = key_f3; + //m_keymap[VK_F4] = key_f4; + //m_keymap[VK_F5] = key_f5; + //m_keymap[VK_F6] = key_f6; + //m_keymap[VK_F7] = key_f7; + //m_keymap[VK_F8] = key_f8; + //m_keymap[VK_F9] = key_f9; + //m_keymap[VK_F10] = key_f10; + //m_keymap[VK_F11] = key_f11; + //m_keymap[VK_F12] = key_f12; + //m_keymap[VK_F13] = key_f13; + //m_keymap[VK_F14] = key_f14; + //m_keymap[VK_F15] = key_f15; + + //m_keymap[VK_NUMLOCK] = key_numlock; + //m_keymap[VK_CAPITAL] = key_capslock; + //m_keymap[VK_SCROLL] = key_scrollock; + + switch(m_format) + { + case pix_format_gray8: + m_sys_format = pix_format_gray8; + m_bpp = 8; + m_sys_bpp = 8; + break; + + case pix_format_rgb565: + case pix_format_rgb555: + m_sys_format = pix_format_rgb555; + m_bpp = 16; + m_sys_bpp = 16; + break; + + case pix_format_rgb24: + case pix_format_bgr24: + m_sys_format = pix_format_rgb24; + m_bpp = 24; + m_sys_bpp = 24; + break; + + case pix_format_bgra32: + case pix_format_abgr32: + case pix_format_argb32: + case pix_format_rgba32: + m_sys_format = pix_format_argb32; + m_bpp = 32; + m_sys_bpp = 32; + break; + } + ::Microseconds(&m_sw_freq); + ::Microseconds(&m_sw_start); + } + + + //------------------------------------------------------------------------ + void platform_specific::create_pmap(unsigned width, + unsigned height, + rendering_buffer* wnd) + { + m_pmap_window.create(width, height, org_e(m_bpp)); + wnd->attach(m_pmap_window.buf(), + m_pmap_window.width(), + m_pmap_window.height(), + m_flip_y ? + -m_pmap_window.row_bytes() : + m_pmap_window.row_bytes()); + } + + + //------------------------------------------------------------------------ + void platform_specific::display_pmap(WindowRef window, const rendering_buffer* src) + { + if(m_sys_format == m_format) + { + m_pmap_window.draw(window); + } + else + { + pixel_map pmap_tmp; + pmap_tmp.create(m_pmap_window.width(), + m_pmap_window.height(), + org_e(m_sys_bpp)); + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + -pmap_tmp.row_bytes() : + pmap_tmp.row_bytes()); + + switch(m_format) + { + case pix_format_gray8: + return; + + case pix_format_rgb565: + color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); + break; + + case pix_format_bgr24: + color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb24()); + break; + + case pix_format_abgr32: + color_conv(&rbuf_tmp, src, color_conv_abgr32_to_argb32()); + break; + + case pix_format_bgra32: + color_conv(&rbuf_tmp, src, color_conv_bgra32_to_argb32()); + break; + + case pix_format_rgba32: + color_conv(&rbuf_tmp, src, color_conv_rgba32_to_argb32()); + break; + } + pmap_tmp.draw(window); + } + } + + + //------------------------------------------------------------------------ + bool platform_specific::save_pmap(const char* fn, unsigned idx, + const rendering_buffer* src) + { + if(m_sys_format == m_format) + { + return m_pmap_img[idx].save_as_qt(fn); + } + else + { + pixel_map pmap_tmp; + pmap_tmp.create(m_pmap_img[idx].width(), + m_pmap_img[idx].height(), + org_e(m_sys_bpp)); + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + -pmap_tmp.row_bytes() : + pmap_tmp.row_bytes()); + switch(m_format) + { + case pix_format_gray8: + return false; + + case pix_format_rgb565: + color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); + break; + + case pix_format_rgb24: + color_conv(&rbuf_tmp, src, color_conv_rgb24_to_bgr24()); + break; + + case pix_format_abgr32: + color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32()); + break; + + case pix_format_argb32: + color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32()); + break; + + case pix_format_rgba32: + color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32()); + break; + } + return pmap_tmp.save_as_qt(fn); + } + return true; + } + + + + //------------------------------------------------------------------------ + bool platform_specific::load_pmap(const char* fn, unsigned idx, + rendering_buffer* dst) + { + pixel_map pmap_tmp; + if(!pmap_tmp.load_from_qt(fn)) return false; + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + -pmap_tmp.row_bytes() : + pmap_tmp.row_bytes()); + + m_pmap_img[idx].create(pmap_tmp.width(), + pmap_tmp.height(), + org_e(m_bpp), + 0); + + dst->attach(m_pmap_img[idx].buf(), + m_pmap_img[idx].width(), + m_pmap_img[idx].height(), + m_flip_y ? + -m_pmap_img[idx].row_bytes() : + m_pmap_img[idx].row_bytes()); + + switch(m_format) + { + case pix_format_gray8: + return false; + break; + + case pix_format_rgb555: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb555()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb555()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb555()); break; + } + break; + + case pix_format_rgb565: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb565()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb565()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb565()); break; + } + break; + + case pix_format_rgb24: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb24()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb24()); break; + } + break; + + case pix_format_bgr24: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_bgr24()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_bgr24()); break; + } + break; + + case pix_format_abgr32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_abgr32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_abgr32()); break; + } + break; + + case pix_format_argb32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_argb32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_argb32()); break; + } + break; + + case pix_format_bgra32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_bgra32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_bgra32()); break; + } + break; + + case pix_format_rgba32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgba32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgba32()); break; + } + break; + } + + return true; + } + + + + + + + + + //------------------------------------------------------------------------ + unsigned platform_specific::translate(unsigned keycode) + { + return m_last_translated_key = (keycode > 255) ? 0 : m_keymap[keycode]; + } + + + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(format, flip_y)), + m_format(format), + m_bpp(m_specific->m_bpp), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y), + m_initial_width(10), + m_initial_height(10) + { + std::strcpy(m_caption, "Anti-Grain Geometry Application"); + } + + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + std::strcpy(m_caption, cap); + if(m_specific->m_window) + { + SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, cap, kCFStringEncodingASCII, nil)); + } + } + + + + //------------------------------------------------------------------------ + static unsigned get_key_flags(UInt32 wflags) + { + unsigned flags = 0; + + if(wflags & shiftKey) flags |= kbd_shift; + if(wflags & controlKey) flags |= kbd_ctrl; + + return flags; + } + + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + SInt16 item; + Str255 p_msg; + + ::CopyCStringToPascal (msg, p_msg); + ::StandardAlert (kAlertPlainAlert, (const unsigned char*) "\013AGG Message", p_msg, NULL, &item); + //::StandardAlert (kAlertPlainAlert, (const unsigned char*) "\pAGG Message", p_msg, NULL, &item); + } + + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + ::Microseconds (&(m_specific->m_sw_start)); + } + + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + UnsignedWide stop; + ::Microseconds(&stop); + return double(stop.lo - + m_specific->m_sw_start.lo) * 1e6 / + double(m_specific->m_sw_freq.lo); + } + + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, unsigned flags) + { + if(m_specific->m_sys_format == pix_format_undefined) + { + return false; + } + + m_window_flags = flags; + + // application + EventTypeSpec eventType; + EventHandlerUPP handlerUPP; + + eventType.eventClass = kEventClassApplication; + eventType.eventKind = kEventAppQuit; + + handlerUPP = NewEventHandlerUPP(DoAppQuit); + + InstallApplicationEventHandler (handlerUPP, 1, &eventType, nil, nil); + + eventType.eventClass = kEventClassMouse; + eventType.eventKind = kEventMouseDown; + handlerUPP = NewEventHandlerUPP(DoMouseDown); + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + eventType.eventKind = kEventMouseUp; + handlerUPP = NewEventHandlerUPP(DoMouseUp); + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + eventType.eventKind = kEventMouseDragged; + handlerUPP = NewEventHandlerUPP(DoMouseDragged); + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + eventType.eventClass = kEventClassKeyboard; + eventType.eventKind = kEventRawKeyDown; + handlerUPP = NewEventHandlerUPP(DoKeyDown); + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + eventType.eventKind = kEventRawKeyUp; + handlerUPP = NewEventHandlerUPP(DoKeyUp); + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + eventType.eventKind = kEventRawKeyRepeat; + handlerUPP = NewEventHandlerUPP(DoKeyDown); // 'key repeat' is translated to 'key down' + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + WindowAttributes windowAttrs; + Rect bounds; + + // window + windowAttrs = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute; + SetRect (&bounds, 0, 0, width, height); + OffsetRect (&bounds, 100, 100); + CreateNewWindow (kDocumentWindowClass, windowAttrs, &bounds, &m_specific->m_window); + + if(m_specific->m_window == nil) + { + return false; + } + + // I assume the text is ASCII. + // Change to kCFStringEncodingMacRoman, kCFStringEncodingISOLatin1, kCFStringEncodingUTF8 or what else you need. + SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, m_caption, kCFStringEncodingASCII, nil)); + + eventType.eventClass = kEventClassWindow; + eventType.eventKind = kEventWindowClose; + + handlerUPP = NewEventHandlerUPP(DoWindowClose); + InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL); + + eventType.eventKind = kEventWindowDrawContent; + handlerUPP = NewEventHandlerUPP(DoWindowDrawContent); + InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL); + + // Periodic task + // Instead of an idle function I use the Carbon event timer. + // You may decide to change the wait value which is currently 50 milliseconds. + EventLoopRef mainLoop; + EventLoopTimerUPP timerUPP; + EventLoopTimerRef theTimer; + + mainLoop = GetMainEventLoop(); + timerUPP = NewEventLoopTimerUPP (DoPeriodicTask); + InstallEventLoopTimer (mainLoop, 0, 50 * kEventDurationMillisecond, timerUPP, this, &theTimer); + + m_specific->create_pmap(width, height, &m_rbuf_window); + m_initial_width = width; + m_initial_height = height; + on_init(); + on_resize(width, height); + m_specific->m_redraw_flag = true; + + ShowWindow (m_specific->m_window); + SetPortWindowPort (m_specific->m_window); + + return true; + } + + + //------------------------------------------------------------------------ + int platform_support::run() + { + + RunApplicationEventLoop (); + return true; + } + + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const { return ".bmp"; } + + //------------------------------------------------------------------------ + const char* platform_support::full_file_name(const char* file_name) + { + return file_name; + } + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + char fn[1024]; + std::strcpy(fn, file); + int len = std::strlen(fn); +#if defined(__MWERKS__) + if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0) +#else + if(len < 4 || strncasecmp(fn + len - 4, ".BMP", 4) != 0) +#endif + { + std::strcat(fn, ".bmp"); + } + return m_specific->load_pmap(fn, idx, &m_rbuf_img[idx]); + } + return true; + } + + + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + char fn[1024]; + std::strcpy(fn, file); + int len = std::strlen(fn); +#if defined(__MWERKS__) + if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0) +#else + if(len < 4 || strncasecmp(fn + len - 4, ".BMP", 4) != 0) +#endif + { + std::strcat(fn, ".bmp"); + } + return m_specific->save_pmap(fn, idx, &m_rbuf_img[idx]); + } + return true; + } + + + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) + { + if(idx < max_images) + { + if(width == 0) width = m_specific->m_pmap_window.width(); + if(height == 0) height = m_specific->m_pmap_window.height(); + m_specific->m_pmap_img[idx].create(width, height, org_e(m_specific->m_bpp)); + m_rbuf_img[idx].attach(m_specific->m_pmap_img[idx].buf(), + m_specific->m_pmap_img[idx].width(), + m_specific->m_pmap_img[idx].height(), + m_flip_y ? + -m_specific->m_pmap_img[idx].row_bytes() : + m_specific->m_pmap_img[idx].row_bytes()); + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + Rect bounds; + + m_specific->m_redraw_flag = true; + // on_ctrl_change (); + on_draw(); + + SetRect(&bounds, 0, 0, m_rbuf_window.width(), m_rbuf_window.height()); + InvalWindowRect(m_specific->m_window, &bounds); + } + + + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + m_specific->display_pmap(m_specific->m_window, &m_rbuf_window); + } + + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} + + +//------------------------------------------------------------------------ +pascal OSStatus DoWindowClose (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + userData; + + QuitApplicationEventLoop (); + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoAppQuit (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + userData; + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoMouseDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + Point wheresMyMouse; + UInt32 modifier; + + GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse); + GlobalToLocal (&wheresMyMouse); + GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); + + platform_support * app = reinterpret_cast<platform_support*>(userData); + + app->m_specific->m_cur_x = wheresMyMouse.h; + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v; + } + else + { + app->m_specific->m_cur_y = wheresMyMouse.v; + } + app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier); + + app->m_ctrls.set_cur(app->m_specific->m_cur_x, + app->m_specific->m_cur_y); + if(app->m_ctrls.on_mouse_button_down(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + if(app->m_ctrls.in_rect(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + if(app->m_ctrls.set_cur(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + } + else + { + app->on_mouse_button_down(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); + } + } + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + Point wheresMyMouse; + UInt32 modifier; + + GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse); + GlobalToLocal (&wheresMyMouse); + GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); + + platform_support * app = reinterpret_cast<platform_support*>(userData); + + app->m_specific->m_cur_x = wheresMyMouse.h; + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v; + } + else + { + app->m_specific->m_cur_y = wheresMyMouse.v; + } + app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier); + + if(app->m_ctrls.on_mouse_button_up(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + app->on_mouse_button_up(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoMouseDragged (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + Point wheresMyMouse; + UInt32 modifier; + + GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse); + GlobalToLocal (&wheresMyMouse); + GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); + + platform_support * app = reinterpret_cast<platform_support*>(userData); + + app->m_specific->m_cur_x = wheresMyMouse.h; + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v; + } + else + { + app->m_specific->m_cur_y = wheresMyMouse.v; + } + app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier); + + + if(app->m_ctrls.on_mouse_move( + app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + (app->m_specific->m_input_flags & mouse_left) != 0)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + app->on_mouse_move(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); + } + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoKeyDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + char key_code; + UInt32 modifier; + + GetEventParameter (theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key_code); + GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); + + platform_support * app = reinterpret_cast<platform_support*>(userData); + + app->m_specific->m_last_translated_key = 0; + switch(modifier) + { + case controlKey: + app->m_specific->m_input_flags |= kbd_ctrl; + break; + + case shiftKey: + app->m_specific->m_input_flags |= kbd_shift; + break; + + default: + app->m_specific->translate(key_code); + break; + } + + if(app->m_specific->m_last_translated_key) + { + bool left = false; + bool up = false; + bool right = false; + bool down = false; + + switch(app->m_specific->m_last_translated_key) + { + case key_left: + left = true; + break; + + case key_up: + up = true; + break; + + case key_right: + right = true; + break; + + case key_down: + down = true; + break; + + //On a Mac, screenshots are handled by the system. + case key_f2: + app->copy_window_to_img(agg::platform_support::max_images - 1); + app->save_img(agg::platform_support::max_images - 1, "screenshot"); + break; + } + + + if(app->m_ctrls.on_arrow_keys(left, right, down, up)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + app->on_key(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_last_translated_key, + app->m_specific->m_input_flags); + } + } + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoKeyUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + char key_code; + UInt32 modifier; + + GetEventParameter (theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key_code); + GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); + + platform_support * app = reinterpret_cast<platform_support*>(userData); + + app->m_specific->m_last_translated_key = 0; + switch(modifier) + { + case controlKey: + app->m_specific->m_input_flags &= ~kbd_ctrl; + break; + + case shiftKey: + app->m_specific->m_input_flags &= ~kbd_shift; + break; + } + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoWindowDrawContent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + platform_support * app = reinterpret_cast<platform_support*>(userData); + + if(app) + { + if(app->m_specific->m_redraw_flag) + { + app->on_draw(); + app->m_specific->m_redraw_flag = false; + } + app->m_specific->display_pmap(app->m_specific->m_window, &app->rbuf_window()); + } + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal void DoPeriodicTask (EventLoopTimerRef theTimer, void* userData) +{ + platform_support * app = reinterpret_cast<platform_support*>(userData); + + if(!app->wait_mode()) + app->on_idle(); +} + + +} + + + + +//---------------------------------------------------------------------------- +int agg_main(int argc, char* argv[]); + + +// Hm. Classic MacOS does not know command line input. +// CodeWarrior provides a way to mimic command line input. +// The function 'ccommand' can be used to get the command +// line arguments. +//---------------------------------------------------------------------------- +int main(int argc, char* argv[]) +{ +#if defined(__MWERKS__) + // argc = ccommand (&argv); +#endif + + // Check if we are launched by double-clicking under OSX + // Get rid of extra argument, this will confuse the standard argument parsing + // calls used in the examples to get the name of the image file to be used + if ( argc >= 2 && std::strncmp(argv[1], "-psn", 4) == 0 ) { + argc = 1; + } + +launch: + return agg_main(argc, argv); +} diff --git a/src/platform/sdl/Makefile.am b/src/platform/sdl/Makefile.am new file mode 100644 index 0000000..590ef82 --- /dev/null +++ b/src/platform/sdl/Makefile.am @@ -0,0 +1,10 @@ +if ENABLE_SDL + +lib_LTLIBRARIES = libaggplatformsdl.la + +libaggplatformsdl_la_LDFLAGS = -version-info @AGG_LIB_VERSION@ +libaggplatformsdl_la_SOURCES = agg_platform_support.cpp +libaggplatformsdl_la_CXXFLAGS = -I$(top_srcdir)/include @SDL_CFLAGS@ +libaggplatformsdl_la_LIBADD = @SDL_LIBS@ +endif + diff --git a/src/platform/sdl/agg_platform_support.cpp b/src/platform/sdl/agg_platform_support.cpp new file mode 100644 index 0000000..107626a --- /dev/null +++ b/src/platform/sdl/agg_platform_support.cpp @@ -0,0 +1,709 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class platform_support. SDL version. +// +//---------------------------------------------------------------------------- + +#include <cstring> +#include <cstdio> +#include "platform/agg_platform_support.h" +#include "SDL.h" +#include "SDL_byteorder.h" + + +namespace agg +{ + + //------------------------------------------------------------------------ + class platform_specific + { + public: + platform_specific(pix_format_e format, bool flip_y); + ~platform_specific(); + + pix_format_e m_format; + pix_format_e m_sys_format; + bool m_flip_y; + unsigned m_bpp; + unsigned m_sys_bpp; + unsigned m_rmask; + unsigned m_gmask; + unsigned m_bmask; + unsigned m_amask; + bool m_update_flag; + bool m_resize_flag; + bool m_initialized; + SDL_Surface* m_surf_screen; + SDL_Surface* m_surf_window; + SDL_Surface* m_surf_img[platform_support::max_images]; + int m_cur_x; + int m_cur_y; + int m_sw_start; + }; + + + + //------------------------------------------------------------------------ + platform_specific::platform_specific(pix_format_e format, bool flip_y) : + m_format(format), + m_sys_format(pix_format_undefined), + m_flip_y(flip_y), + m_bpp(0), + m_sys_bpp(0), + m_update_flag(true), + m_resize_flag(true), + m_initialized(false), + m_surf_screen(0), + m_surf_window(0), + m_cur_x(0), + m_cur_y(0) + { + std::memset(m_surf_img, 0, sizeof(m_surf_img)); + + switch(m_format) + { + case pix_format_gray8: + m_bpp = 8; + break; + + case pix_format_rgb565: + m_rmask = 0xF800; + m_gmask = 0x7E0; + m_bmask = 0x1F; + m_amask = 0; + m_bpp = 16; + break; + + case pix_format_rgb555: + m_rmask = 0x7C00; + m_gmask = 0x3E0; + m_bmask = 0x1F; + m_amask = 0; + m_bpp = 16; + break; + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + case pix_format_rgb24: + m_rmask = 0xFF; + m_gmask = 0xFF00; + m_bmask = 0xFF0000; + m_amask = 0; + m_bpp = 24; + break; + + case pix_format_bgr24: + m_rmask = 0xFF0000; + m_gmask = 0xFF00; + m_bmask = 0xFF; + m_amask = 0; + m_bpp = 24; + break; + + case pix_format_bgra32: + m_rmask = 0xFF0000; + m_gmask = 0xFF00; + m_bmask = 0xFF; + m_amask = 0xFF000000; + m_bpp = 32; + break; + + case pix_format_abgr32: + m_rmask = 0xFF000000; + m_gmask = 0xFF0000; + m_bmask = 0xFF00; + m_amask = 0xFF; + m_bpp = 32; + break; + + case pix_format_argb32: + m_rmask = 0xFF00; + m_gmask = 0xFF0000; + m_bmask = 0xFF000000; + m_amask = 0xFF; + m_bpp = 32; + break; + + case pix_format_rgba32: + m_rmask = 0xFF; + m_gmask = 0xFF00; + m_bmask = 0xFF0000; + m_amask = 0xFF000000; + m_bpp = 32; + break; +#else //SDL_BIG_ENDIAN (PPC) + case pix_format_rgb24: + m_rmask = 0xFF0000; + m_gmask = 0xFF00; + m_bmask = 0xFF; + m_amask = 0; + m_bpp = 24; + break; + + case pix_format_bgr24: + m_rmask = 0xFF; + m_gmask = 0xFF00; + m_bmask = 0xFF0000; + m_amask = 0; + m_bpp = 24; + break; + + case pix_format_bgra32: + m_rmask = 0xFF00; + m_gmask = 0xFF0000; + m_bmask = 0xFF000000; + m_amask = 0xFF; + m_bpp = 32; + break; + + case pix_format_abgr32: + m_rmask = 0xFF; + m_gmask = 0xFF00; + m_bmask = 0xFF0000; + m_amask = 0xFF000000; + m_bpp = 32; + break; + + case pix_format_argb32: + m_rmask = 0xFF0000; + m_gmask = 0xFF00; + m_bmask = 0xFF; + m_amask = 0xFF000000; + m_bpp = 32; + break; + + case pix_format_rgba32: + m_rmask = 0xFF000000; + m_gmask = 0xFF0000; + m_bmask = 0xFF00; + m_amask = 0xFF; + m_bpp = 32; + break; +#endif + } + } + + //------------------------------------------------------------------------ + platform_specific::~platform_specific() + { + int i; + for(i = platform_support::max_images - 1; i >= 0; --i) + { + if(m_surf_img[i]) SDL_FreeSurface(m_surf_img[i]); + } + if(m_surf_window) SDL_FreeSurface(m_surf_window); + if(m_surf_screen) SDL_FreeSurface(m_surf_screen); + } + + + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(format, flip_y)), + m_format(format), + m_bpp(m_specific->m_bpp), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y) + { + SDL_Init(SDL_INIT_VIDEO); + std::strcpy(m_caption, "Anti-Grain Geometry Application"); + } + + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + std::strcpy(m_caption, cap); + if(m_specific->m_initialized) + { + SDL_WM_SetCaption(cap, 0); + } + } + + + + + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, unsigned flags) + { + m_window_flags = flags; + unsigned wflags = SDL_SWSURFACE; + + if(m_window_flags & window_hw_buffer) + { + wflags = SDL_HWSURFACE; + } + + if(m_window_flags & window_resize) + { + wflags |= SDL_RESIZABLE; + } + + if(m_specific->m_surf_screen) SDL_FreeSurface(m_specific->m_surf_screen); + + m_specific->m_surf_screen = SDL_SetVideoMode(width, height, m_bpp, wflags); + if(m_specific->m_surf_screen == 0) + { + std::fprintf(stderr, + "Unable to set %dx%d %d bpp video: %s\n", + width, + height, + m_bpp, + ::SDL_GetError()); + return false; + } + + SDL_WM_SetCaption(m_caption, 0); + + if(m_specific->m_surf_window) SDL_FreeSurface(m_specific->m_surf_window); + + m_specific->m_surf_window = + SDL_CreateRGBSurface(SDL_HWSURFACE, + m_specific->m_surf_screen->w, + m_specific->m_surf_screen->h, + m_specific->m_surf_screen->format->BitsPerPixel, + m_specific->m_rmask, + m_specific->m_gmask, + m_specific->m_bmask, + m_specific->m_amask); + + if(m_specific->m_surf_window == 0) + { + std::fprintf(stderr, + "Unable to create image buffer %dx%d %d bpp: %s\n", + width, + height, + m_bpp, + SDL_GetError()); + return false; + } + + m_rbuf_window.attach((unsigned char*)m_specific->m_surf_window->pixels, + m_specific->m_surf_window->w, + m_specific->m_surf_window->h, + m_flip_y ? -m_specific->m_surf_window->pitch : + m_specific->m_surf_window->pitch); + + if(!m_specific->m_initialized) + { + m_initial_width = width; + m_initial_height = height; + on_init(); + m_specific->m_initialized = true; + } + on_resize(m_rbuf_window.width(), m_rbuf_window.height()); + m_specific->m_update_flag = true; + return true; + } + + + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + SDL_BlitSurface(m_specific->m_surf_window, 0, m_specific->m_surf_screen, 0); + SDL_UpdateRect(m_specific->m_surf_screen, 0, 0, 0, 0); + } + + + //------------------------------------------------------------------------ + int platform_support::run() + { + SDL_Event event; + bool ev_flag = false; + + for(;;) + { + if(m_specific->m_update_flag) + { + on_draw(); + update_window(); + m_specific->m_update_flag = false; + } + + ev_flag = false; + if(m_wait_mode) + { + SDL_WaitEvent(&event); + ev_flag = true; + } + else + { + if(SDL_PollEvent(&event)) + { + ev_flag = true; + } + else + { + on_idle(); + } + } + + if(ev_flag) + { + if(event.type == SDL_QUIT) + { + break; + } + + int y; + unsigned flags = 0; + + switch (event.type) + { + case SDL_VIDEORESIZE: + if(!init(event.resize.w, event.resize.h, m_window_flags)) return false; + on_resize(m_rbuf_window.width(), m_rbuf_window.height()); + trans_affine_resizing(event.resize.w, event.resize.h); + m_specific->m_update_flag = true; + break; + + case SDL_KEYDOWN: + { + flags = 0; + if(event.key.keysym.mod & KMOD_SHIFT) flags |= kbd_shift; + if(event.key.keysym.mod & KMOD_CTRL) flags |= kbd_ctrl; + + bool left = false; + bool up = false; + bool right = false; + bool down = false; + + switch(event.key.keysym.sym) + { + case key_left: + left = true; + break; + + case key_up: + up = true; + break; + + case key_right: + right = true; + break; + + case key_down: + down = true; + break; + } + + if(m_ctrls.on_arrow_keys(left, right, down, up)) + { + on_ctrl_change(); + force_redraw(); + } + else + { + on_key(m_specific->m_cur_x, + m_specific->m_cur_y, + event.key.keysym.sym, + flags); + } + } + break; + + case SDL_MOUSEMOTION: + y = m_flip_y ? + m_rbuf_window.height() - event.motion.y : + event.motion.y; + + m_specific->m_cur_x = event.motion.x; + m_specific->m_cur_y = y; + flags = 0; + if(event.motion.state & SDL_BUTTON_LMASK) flags |= mouse_left; + if(event.motion.state & SDL_BUTTON_RMASK) flags |= mouse_right; + + if(m_ctrls.on_mouse_move(m_specific->m_cur_x, + m_specific->m_cur_y, + (flags & mouse_left) != 0)) + { + on_ctrl_change(); + force_redraw(); + } + else + { + on_mouse_move(m_specific->m_cur_x, + m_specific->m_cur_y, + flags); + } + SDL_Event eventtrash; + while (SDL_PeepEvents(&eventtrash, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION))!=0){;} + break; + + case SDL_MOUSEBUTTONDOWN: + y = m_flip_y + ? m_rbuf_window.height() - event.button.y + : event.button.y; + + m_specific->m_cur_x = event.button.x; + m_specific->m_cur_y = y; + flags = 0; + switch(event.button.button) + { + case SDL_BUTTON_LEFT: + { + flags = mouse_left; + +if(m_ctrls.on_mouse_button_down(m_specific->m_cur_x, + m_specific->m_cur_y)) + { + m_ctrls.set_cur(m_specific->m_cur_x, + m_specific->m_cur_y); + on_ctrl_change(); + force_redraw(); + } + else + { + if(m_ctrls.in_rect(m_specific->m_cur_x, + m_specific->m_cur_y)) + { + if(m_ctrls.set_cur(m_specific->m_cur_x, + m_specific->m_cur_y)) + { + on_ctrl_change(); + force_redraw(); + } + } + else + { + on_mouse_button_down(m_specific->m_cur_x, + m_specific->m_cur_y, + flags); + } + } + } + break; + case SDL_BUTTON_RIGHT: + flags = mouse_right; + on_mouse_button_down(m_specific->m_cur_x, + m_specific->m_cur_y, + flags); + break; + } //switch(event.button.button) + break; + + case SDL_MOUSEBUTTONUP: + y = m_flip_y + ? m_rbuf_window.height() - event.button.y + : event.button.y; + + m_specific->m_cur_x = event.button.x; + m_specific->m_cur_y = y; + flags = 0; + if(m_ctrls.on_mouse_button_up(m_specific->m_cur_x, + m_specific->m_cur_y)) + { + on_ctrl_change(); + force_redraw(); + } + on_mouse_button_up(m_specific->m_cur_x, + m_specific->m_cur_y, + flags); + break; + } + } + } + return 0; + } + + + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const { return ".bmp"; } + + //------------------------------------------------------------------------ + const char* platform_support::full_file_name(const char* file_name) + { + return file_name; + } + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + if(m_specific->m_surf_img[idx]) SDL_FreeSurface(m_specific->m_surf_img[idx]); + + char fn[1024]; + std::strcpy(fn, file); + int len = std::strlen(fn); + if(len < 4 || std::strcmp(fn + len - 4, ".bmp") != 0) + { + std::strcat(fn, ".bmp"); + } + + SDL_Surface* tmp_surf = SDL_LoadBMP(fn); + if (tmp_surf == 0) + { + std::fprintf(stderr, "Couldn't load %s: %s\n", fn, SDL_GetError()); + return false; + } + + SDL_PixelFormat format; + format.palette = 0; + format.BitsPerPixel = m_bpp; + format.BytesPerPixel = m_bpp >> 8; + format.Rmask = m_specific->m_rmask; + format.Gmask = m_specific->m_gmask; + format.Bmask = m_specific->m_bmask; + format.Amask = m_specific->m_amask; + format.Rshift = 0; + format.Gshift = 0; + format.Bshift = 0; + format.Ashift = 0; + format.Rloss = 0; + format.Gloss = 0; + format.Bloss = 0; + format.Aloss = 0; + format.colorkey = 0; + format.alpha = 0; + + m_specific->m_surf_img[idx] = + SDL_ConvertSurface(tmp_surf, + &format, + SDL_SWSURFACE); + + SDL_FreeSurface(tmp_surf); + + if(m_specific->m_surf_img[idx] == 0) return false; + + m_rbuf_img[idx].attach((unsigned char*)m_specific->m_surf_img[idx]->pixels, + m_specific->m_surf_img[idx]->w, + m_specific->m_surf_img[idx]->h, + m_flip_y ? -m_specific->m_surf_img[idx]->pitch : + m_specific->m_surf_img[idx]->pitch); + return true; + + } + return false; + } + + + + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + if(idx < max_images && m_specific->m_surf_img[idx]) + { + char fn[1024]; + std::strcpy(fn, file); + int len = std::strlen(fn); + if(len < 4 || std::strcmp(fn + len - 4, ".bmp") != 0) + { + std::strcat(fn, ".bmp"); + } + return SDL_SaveBMP(m_specific->m_surf_img[idx], fn) == 0; + } + return false; + } + + + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) + { + if(idx < max_images) + { + + if(m_specific->m_surf_img[idx]) SDL_FreeSurface(m_specific->m_surf_img[idx]); + + m_specific->m_surf_img[idx] = + SDL_CreateRGBSurface(SDL_SWSURFACE, + width, + height, + m_specific->m_surf_screen->format->BitsPerPixel, + m_specific->m_rmask, + m_specific->m_gmask, + m_specific->m_bmask, + m_specific->m_amask); + if(m_specific->m_surf_img[idx] == 0) + { + std::fprintf(stderr, "Couldn't create image: %s\n", SDL_GetError()); + return false; + } + + m_rbuf_img[idx].attach((unsigned char*)m_specific->m_surf_img[idx]->pixels, + m_specific->m_surf_img[idx]->w, + m_specific->m_surf_img[idx]->h, + m_flip_y ? -m_specific->m_surf_img[idx]->pitch : + m_specific->m_surf_img[idx]->pitch); + + return true; + } + + return false; + } + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + m_specific->m_sw_start = SDL_GetTicks(); + } + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + int stop = SDL_GetTicks(); + return double(stop - m_specific->m_sw_start); + } + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + std::fprintf(stderr, "%s\n", msg); + } + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + m_specific->m_update_flag = true; + } + + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} + + +} + + +int agg_main(int argc, char* argv[]); + +int main(int argc, char* argv[]) +{ + return agg_main(argc, argv); +} + diff --git a/src/platform/win32/Makefile.am b/src/platform/win32/Makefile.am new file mode 100644 index 0000000..df7a675 --- /dev/null +++ b/src/platform/win32/Makefile.am @@ -0,0 +1,13 @@ + + +if ENABLE_WIN32 +lib_LTLIBRARIES = libaggplatformwin32.la + +libaggplatformwin32_la_LDFLAGS = -version-info @AGG_LIB_VERSION@ +libaggplatformwin32_la_SOURCES = agg_platform_support.cpp \ + agg_win32_bmp.cpp + +libaggplatformwin32_la_CXXFLAGS = -I$(top_srcdir)/include @WINDOWS_CFLAGS@ +libaggplatformwin32_la_LIBADD = @WINDOWS_LIBS@ $(top_builddir)/src/libagg.la +endif + diff --git a/src/platform/win32/agg_platform_support.cpp b/src/platform/win32/agg_platform_support.cpp new file mode 100644 index 0000000..d6ffa88 --- /dev/null +++ b/src/platform/win32/agg_platform_support.cpp @@ -0,0 +1,1655 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-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 +//---------------------------------------------------------------------------- +// +// class platform_support +// +//---------------------------------------------------------------------------- + +#include <windows.h> +#include <cstring> +#include "platform/agg_platform_support.h" +#include "platform/win32/agg_win32_bmp.h" +#include "util/agg_color_conv.h" +#include "util/agg_color_conv_rgb8.h" +#include "util/agg_color_conv_rgb16.h" +#include "agg_pixfmt_gray.h" +#include "agg_pixfmt_rgb.h" +#include "agg_pixfmt_rgba.h" + + +namespace agg +{ + + //------------------------------------------------------------------------ + HINSTANCE g_windows_instance = 0; + int g_windows_cmd_show = 0; + + + //------------------------------------------------------------------------ + class platform_specific + { + public: + platform_specific(pix_format_e format, bool flip_y); + + void create_pmap(unsigned width, unsigned height, + rendering_buffer* wnd); + + void display_pmap(HDC dc, const rendering_buffer* src); + bool load_pmap(const char* fn, unsigned idx, + rendering_buffer* dst); + + bool save_pmap(const char* fn, unsigned idx, + const rendering_buffer* src); + + unsigned translate(unsigned keycode); + + pix_format_e m_format; + pix_format_e m_sys_format; + bool m_flip_y; + unsigned m_bpp; + unsigned m_sys_bpp; + HWND m_hwnd; + pixel_map m_pmap_window; + pixel_map m_pmap_img[platform_support::max_images]; + unsigned m_keymap[256]; + unsigned m_last_translated_key; + int m_cur_x; + int m_cur_y; + unsigned m_input_flags; + bool m_redraw_flag; + HDC m_current_dc; + LARGE_INTEGER m_sw_freq; + LARGE_INTEGER m_sw_start; + }; + + + //------------------------------------------------------------------------ + platform_specific::platform_specific(pix_format_e format, bool flip_y) : + m_format(format), + m_sys_format(pix_format_undefined), + m_flip_y(flip_y), + m_bpp(0), + m_sys_bpp(0), + m_hwnd(0), + m_last_translated_key(0), + m_cur_x(0), + m_cur_y(0), + m_input_flags(0), + m_redraw_flag(true), + m_current_dc(0) + { + memset(m_keymap, 0, sizeof(m_keymap)); + + m_keymap[VK_PAUSE] = key_pause; + m_keymap[VK_CLEAR] = key_clear; + + m_keymap[VK_NUMPAD0] = key_kp0; + m_keymap[VK_NUMPAD1] = key_kp1; + m_keymap[VK_NUMPAD2] = key_kp2; + m_keymap[VK_NUMPAD3] = key_kp3; + m_keymap[VK_NUMPAD4] = key_kp4; + m_keymap[VK_NUMPAD5] = key_kp5; + m_keymap[VK_NUMPAD6] = key_kp6; + m_keymap[VK_NUMPAD7] = key_kp7; + m_keymap[VK_NUMPAD8] = key_kp8; + m_keymap[VK_NUMPAD9] = key_kp9; + m_keymap[VK_DECIMAL] = key_kp_period; + m_keymap[VK_DIVIDE] = key_kp_divide; + m_keymap[VK_MULTIPLY] = key_kp_multiply; + m_keymap[VK_SUBTRACT] = key_kp_minus; + m_keymap[VK_ADD] = key_kp_plus; + + m_keymap[VK_UP] = key_up; + m_keymap[VK_DOWN] = key_down; + m_keymap[VK_RIGHT] = key_right; + m_keymap[VK_LEFT] = key_left; + m_keymap[VK_INSERT] = key_insert; + m_keymap[VK_DELETE] = key_delete; + m_keymap[VK_HOME] = key_home; + m_keymap[VK_END] = key_end; + m_keymap[VK_PRIOR] = key_page_up; + m_keymap[VK_NEXT] = key_page_down; + + m_keymap[VK_F1] = key_f1; + m_keymap[VK_F2] = key_f2; + m_keymap[VK_F3] = key_f3; + m_keymap[VK_F4] = key_f4; + m_keymap[VK_F5] = key_f5; + m_keymap[VK_F6] = key_f6; + m_keymap[VK_F7] = key_f7; + m_keymap[VK_F8] = key_f8; + m_keymap[VK_F9] = key_f9; + m_keymap[VK_F10] = key_f10; + m_keymap[VK_F11] = key_f11; + m_keymap[VK_F12] = key_f12; + m_keymap[VK_F13] = key_f13; + m_keymap[VK_F14] = key_f14; + m_keymap[VK_F15] = key_f15; + + m_keymap[VK_NUMLOCK] = key_numlock; + m_keymap[VK_CAPITAL] = key_capslock; + m_keymap[VK_SCROLL] = key_scrollock; + + + switch(m_format) + { + case pix_format_bw: + m_sys_format = pix_format_bw; + m_bpp = 1; + m_sys_bpp = 1; + break; + + case pix_format_gray8: + case pix_format_sgray8: + m_sys_format = pix_format_sgray8; + m_bpp = 8; + m_sys_bpp = 8; + break; + + case pix_format_gray16: + m_sys_format = pix_format_sgray8; + m_bpp = 16; + m_sys_bpp = 8; + break; + + case pix_format_gray32: + m_sys_format = pix_format_sgray8; + m_bpp = 32; + m_sys_bpp = 8; + break; + + case pix_format_rgb565: + case pix_format_rgb555: + m_sys_format = pix_format_rgb555; + m_bpp = 16; + m_sys_bpp = 16; + break; + + case pix_format_rgbAAA: + case pix_format_bgrAAA: + case pix_format_rgbBBA: + case pix_format_bgrABB: + m_sys_format = pix_format_bgr24; + m_bpp = 32; + m_sys_bpp = 24; + break; + + case pix_format_rgb24: + case pix_format_bgr24: + case pix_format_srgb24: + case pix_format_sbgr24: + m_sys_format = pix_format_sbgr24; + m_bpp = 24; + m_sys_bpp = 24; + break; + + case pix_format_rgb48: + case pix_format_bgr48: + m_sys_format = pix_format_sbgr24; + m_bpp = 48; + m_sys_bpp = 24; + break; + + case pix_format_rgb96: + case pix_format_bgr96: + m_sys_format = pix_format_sbgr24; + m_bpp = 96; + m_sys_bpp = 24; + break; + + case pix_format_bgra32: + case pix_format_abgr32: + case pix_format_argb32: + case pix_format_rgba32: + case pix_format_sbgra32: + case pix_format_sabgr32: + case pix_format_sargb32: + case pix_format_srgba32: + m_sys_format = pix_format_sbgr24; + m_bpp = 32; + m_sys_bpp = 24; + break; + + case pix_format_bgra64: + case pix_format_abgr64: + case pix_format_argb64: + case pix_format_rgba64: + m_sys_format = pix_format_sbgr24; + m_bpp = 64; + m_sys_bpp = 24; + break; + + case pix_format_bgra128: + case pix_format_abgr128: + case pix_format_argb128: + case pix_format_rgba128: + m_sys_format = pix_format_sbgr24; + m_bpp = 128; + m_sys_bpp = 24; + break; + + } + ::QueryPerformanceFrequency(&m_sw_freq); + ::QueryPerformanceCounter(&m_sw_start); + } + + + //------------------------------------------------------------------------ + void platform_specific::create_pmap(unsigned width, + unsigned height, + rendering_buffer* wnd) + { + m_pmap_window.create(width, height, org_e(m_bpp)); + wnd->attach(m_pmap_window.buf(), + m_pmap_window.width(), + m_pmap_window.height(), + m_flip_y ? + m_pmap_window.stride() : + -m_pmap_window.stride()); + } + + + //------------------------------------------------------------------------ + static void convert_pmap(rendering_buffer* dst, + const rendering_buffer* src, + pix_format_e format) + { + switch(format) + { + case pix_format_gray8: + convert<pixfmt_sgray8, pixfmt_gray8>(dst, src); + break; + + case pix_format_gray16: + convert<pixfmt_sgray8, pixfmt_gray16>(dst, src); + break; + + case pix_format_gray32: + convert<pixfmt_sgray8, pixfmt_gray32>(dst, src); + break; + + case pix_format_rgb565: + color_conv(dst, src, color_conv_rgb565_to_rgb555()); + break; + + case pix_format_rgbAAA: + color_conv(dst, src, color_conv_rgbAAA_to_bgr24()); + break; + + case pix_format_bgrAAA: + color_conv(dst, src, color_conv_bgrAAA_to_bgr24()); + break; + + case pix_format_rgbBBA: + color_conv(dst, src, color_conv_rgbBBA_to_bgr24()); + break; + + case pix_format_bgrABB: + color_conv(dst, src, color_conv_bgrABB_to_bgr24()); + break; + + case pix_format_srgb24: + color_conv(dst, src, color_conv_rgb24_to_bgr24()); + break; + + case pix_format_rgb24: + convert<pixfmt_sbgr24, pixfmt_rgb24>(dst, src); + break; + + case pix_format_bgr24: + convert<pixfmt_sbgr24, pixfmt_bgr24>(dst, src); + break; + + case pix_format_rgb48: + convert<pixfmt_sbgr24, pixfmt_rgb48>(dst, src); + break; + + case pix_format_bgr48: + convert<pixfmt_sbgr24, pixfmt_bgr48>(dst, src); + break; + + case pix_format_bgra32: + convert<pixfmt_sbgr24, pixfmt_bgrx32>(dst, src); + break; + + case pix_format_abgr32: + convert<pixfmt_sbgr24, pixfmt_xbgr32>(dst, src); + break; + + case pix_format_argb32: + convert<pixfmt_sbgr24, pixfmt_xrgb32>(dst, src); + break; + + case pix_format_rgba32: + convert<pixfmt_sbgr24, pixfmt_rgbx32>(dst, src); + break; + + case pix_format_sbgra32: + convert<pixfmt_sbgr24, pixfmt_sbgrx32>(dst, src); + break; + + case pix_format_sabgr32: + convert<pixfmt_sbgr24, pixfmt_sxbgr32>(dst, src); + break; + + case pix_format_sargb32: + convert<pixfmt_sbgr24, pixfmt_sxrgb32>(dst, src); + break; + + case pix_format_srgba32: + convert<pixfmt_sbgr24, pixfmt_srgbx32>(dst, src); + break; + + case pix_format_bgra64: + convert<pixfmt_sbgr24, pixfmt_bgrx64>(dst, src); + break; + + case pix_format_abgr64: + convert<pixfmt_sbgr24, pixfmt_xbgr64>(dst, src); + break; + + case pix_format_argb64: + convert<pixfmt_sbgr24, pixfmt_xrgb64>(dst, src); + break; + + case pix_format_rgba64: + convert<pixfmt_sbgr24, pixfmt_rgbx64>(dst, src); + break; + + case pix_format_rgb96: + convert<pixfmt_sbgr24, pixfmt_rgb96>(dst, src); + break; + + case pix_format_bgr96: + convert<pixfmt_sbgr24, pixfmt_bgr96>(dst, src); + break; + + case pix_format_bgra128: + convert<pixfmt_sbgr24, pixfmt_bgrx128>(dst, src); + break; + + case pix_format_abgr128: + convert<pixfmt_sbgr24, pixfmt_xbgr128>(dst, src); + break; + + case pix_format_argb128: + convert<pixfmt_sbgr24, pixfmt_xrgb128>(dst, src); + break; + + case pix_format_rgba128: + convert<pixfmt_sbgr24, pixfmt_rgbx128>(dst, src); + break; + } + } + + + //------------------------------------------------------------------------ + void platform_specific::display_pmap(HDC dc, const rendering_buffer* src) + { + if(m_sys_format == m_format) + { + m_pmap_window.draw(dc); + } + else + { + pixel_map pmap_tmp; + pmap_tmp.create(m_pmap_window.width(), + m_pmap_window.height(), + org_e(m_sys_bpp)); + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + pmap_tmp.stride() : + -pmap_tmp.stride()); + + convert_pmap(&rbuf_tmp, src, m_format); + pmap_tmp.draw(dc); + } + } + + + + //------------------------------------------------------------------------ + bool platform_specific::save_pmap(const char* fn, unsigned idx, + const rendering_buffer* src) + { + if(m_sys_format == m_format) + { + return m_pmap_img[idx].save_as_bmp(fn); + } + + pixel_map pmap_tmp; + pmap_tmp.create(m_pmap_img[idx].width(), + m_pmap_img[idx].height(), + org_e(m_sys_bpp)); + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + pmap_tmp.stride() : + -pmap_tmp.stride()); + + convert_pmap(&rbuf_tmp, src, m_format); + return pmap_tmp.save_as_bmp(fn); + } + + + + //------------------------------------------------------------------------ + bool platform_specific::load_pmap(const char* fn, unsigned idx, + rendering_buffer* dst) + { + pixel_map pmap_tmp; + if(!pmap_tmp.load_from_bmp(fn)) return false; + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + pmap_tmp.stride() : + -pmap_tmp.stride()); + + m_pmap_img[idx].create(pmap_tmp.width(), + pmap_tmp.height(), + org_e(m_bpp), + 0); + + dst->attach(m_pmap_img[idx].buf(), + m_pmap_img[idx].width(), + m_pmap_img[idx].height(), + m_flip_y ? + m_pmap_img[idx].stride() : + -m_pmap_img[idx].stride()); + + switch(m_format) + { + case pix_format_sgray8: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray8()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_gray8()); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray8()); break; + } + break; + + case pix_format_gray8: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_gray8, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_gray16: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray16()); break; + case 24: convert<pixfmt_gray16, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray16()); break; + } + break; + + case pix_format_gray32: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray32()); break; + case 24: convert<pixfmt_gray32, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray32()); break; + } + break; + + case pix_format_rgb555: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb555()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb555()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break; + } + break; + + case pix_format_rgb565: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb565()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb565()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break; + } + break; + + case pix_format_srgb24: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb24()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break; + } + break; + + case pix_format_sbgr24: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgr24()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break; + } + break; + + case pix_format_rgb24: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_rgb24, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgr24: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_bgr24, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgb48: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb48()); break; + case 24: convert<pixfmt_rgb48, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb48()); break; + } + break; + + case pix_format_bgr48: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr48()); break; + case 24: convert<pixfmt_bgr48, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr48()); break; + } + break; + + case pix_format_sabgr32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_abgr32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break; + } + break; + + case pix_format_sargb32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_argb32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break; + } + break; + + case pix_format_sbgra32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgra32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break; + } + break; + + case pix_format_srgba32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgba32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break; + } + break; + + case pix_format_abgr32: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_abgr32, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_argb32: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_argb32, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgra32: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_bgra32, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgba32: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_rgba32, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_abgr64: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_abgr64, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_argb64: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_argb64, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgra64: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_bgra64, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgba64: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_rgba64, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgb96: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_rgb96, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgr96: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_bgr96, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_abgr128: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_abgr128, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_argb128: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_argb128, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgra128: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_bgra128, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgba128: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_rgba128, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + } + + return true; + } + + + + + + + + + //------------------------------------------------------------------------ + unsigned platform_specific::translate(unsigned keycode) + { + return m_last_translated_key = (keycode > 255) ? 0 : m_keymap[keycode]; + } + + + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(format, flip_y)), + m_format(format), + m_bpp(m_specific->m_bpp), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y), + m_initial_width(10), + m_initial_height(10) + { + std::strcpy(m_caption, "Anti-Grain Geometry Application"); + } + + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + std::strcpy(m_caption, cap); + if(m_specific->m_hwnd) + { + SetWindowText(m_specific->m_hwnd, m_caption); + } + } + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + ::QueryPerformanceCounter(&(m_specific->m_sw_start)); + } + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + LARGE_INTEGER stop; + ::QueryPerformanceCounter(&stop); + return double(stop.QuadPart - + m_specific->m_sw_start.QuadPart) * 1000.0 / + double(m_specific->m_sw_freq.QuadPart); + } + + + + //------------------------------------------------------------------------ + static unsigned get_key_flags(int wflags) + { + unsigned flags = 0; + if(wflags & MK_LBUTTON) flags |= mouse_left; + if(wflags & MK_RBUTTON) flags |= mouse_right; + if(wflags & MK_SHIFT) flags |= kbd_shift; + if(wflags & MK_CONTROL) flags |= kbd_ctrl; + return flags; + } + + + void* platform_support::raw_display_handler() + { + return m_specific->m_current_dc; + } + + + //------------------------------------------------------------------------ + LRESULT CALLBACK window_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) + { + PAINTSTRUCT ps; + HDC paintDC; + + + void* user_data = reinterpret_cast<void*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); + platform_support* app = 0; + + if(user_data) + { + app = reinterpret_cast<platform_support*>(user_data); + } + + if(app == 0) + { + if(msg == WM_DESTROY) + { + ::PostQuitMessage(0); + return 0; + } + return ::DefWindowProc(hWnd, msg, wParam, lParam); + } + + HDC dc = ::GetDC(app->m_specific->m_hwnd); + app->m_specific->m_current_dc = dc; + LRESULT ret = 0; + + switch(msg) + { + //-------------------------------------------------------------------- + case WM_CREATE: + break; + + //-------------------------------------------------------------------- + case WM_SIZE: + app->m_specific->create_pmap(LOWORD(lParam), + HIWORD(lParam), + &app->rbuf_window()); + + app->trans_affine_resizing(LOWORD(lParam), HIWORD(lParam)); + app->on_resize(LOWORD(lParam), HIWORD(lParam)); + app->force_redraw(); + break; + + //-------------------------------------------------------------------- + case WM_ERASEBKGND: + break; + + //-------------------------------------------------------------------- + case WM_LBUTTONDOWN: + ::SetCapture(app->m_specific->m_hwnd); + app->m_specific->m_cur_x = int16(LOWORD(lParam)); + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam)); + } + else + { + app->m_specific->m_cur_y = int16(HIWORD(lParam)); + } + app->m_specific->m_input_flags = mouse_left | get_key_flags(wParam); + + app->m_ctrls.set_cur(app->m_specific->m_cur_x, + app->m_specific->m_cur_y); + if(app->m_ctrls.on_mouse_button_down(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + if(app->m_ctrls.in_rect(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + if(app->m_ctrls.set_cur(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + } + else + { + app->on_mouse_button_down(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); + } + } +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + //-------------------------------------------------------------------- + case WM_LBUTTONUP: + ::ReleaseCapture(); + app->m_specific->m_cur_x = int16(LOWORD(lParam)); + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam)); + } + else + { + app->m_specific->m_cur_y = int16(HIWORD(lParam)); + } + app->m_specific->m_input_flags = mouse_left | get_key_flags(wParam); + + if(app->m_ctrls.on_mouse_button_up(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + app->on_mouse_button_up(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + + //-------------------------------------------------------------------- + case WM_RBUTTONDOWN: + ::SetCapture(app->m_specific->m_hwnd); + app->m_specific->m_cur_x = int16(LOWORD(lParam)); + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam)); + } + else + { + app->m_specific->m_cur_y = int16(HIWORD(lParam)); + } + app->m_specific->m_input_flags = mouse_right | get_key_flags(wParam); + app->on_mouse_button_down(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + //-------------------------------------------------------------------- + case WM_RBUTTONUP: + ::ReleaseCapture(); + app->m_specific->m_cur_x = int16(LOWORD(lParam)); + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam)); + } + else + { + app->m_specific->m_cur_y = int16(HIWORD(lParam)); + } + app->m_specific->m_input_flags = mouse_right | get_key_flags(wParam); + app->on_mouse_button_up(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + //-------------------------------------------------------------------- + case WM_MOUSEMOVE: + app->m_specific->m_cur_x = int16(LOWORD(lParam)); + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam)); + } + else + { + app->m_specific->m_cur_y = int16(HIWORD(lParam)); + } + app->m_specific->m_input_flags = get_key_flags(wParam); + + + if(app->m_ctrls.on_mouse_move( + app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + (app->m_specific->m_input_flags & mouse_left) != 0)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + if(!app->m_ctrls.in_rect(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_mouse_move(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); + } + } +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + //-------------------------------------------------------------------- + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + app->m_specific->m_last_translated_key = 0; + switch(wParam) + { + case VK_CONTROL: + app->m_specific->m_input_flags |= kbd_ctrl; + break; + + case VK_SHIFT: + app->m_specific->m_input_flags |= kbd_shift; + break; + + default: + app->m_specific->translate(wParam); + break; + } + + if(app->m_specific->m_last_translated_key) + { + bool left = false; + bool up = false; + bool right = false; + bool down = false; + + switch(app->m_specific->m_last_translated_key) + { + case key_left: + left = true; + break; + + case key_up: + up = true; + break; + + case key_right: + right = true; + break; + + case key_down: + down = true; + break; + + case key_f2: + app->copy_window_to_img(agg::platform_support::max_images - 1); + app->save_img(agg::platform_support::max_images - 1, "screenshot"); + break; + } + + if(app->window_flags() & window_process_all_keys) + { + app->on_key(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_last_translated_key, + app->m_specific->m_input_flags); + } + else + { + if(app->m_ctrls.on_arrow_keys(left, right, down, up)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + app->on_key(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_last_translated_key, + app->m_specific->m_input_flags); + } + } + } +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + //-------------------------------------------------------------------- + case WM_SYSKEYUP: + case WM_KEYUP: + app->m_specific->m_last_translated_key = 0; + switch(wParam) + { + case VK_CONTROL: + app->m_specific->m_input_flags &= ~kbd_ctrl; + break; + + case VK_SHIFT: + app->m_specific->m_input_flags &= ~kbd_shift; + break; + } + break; + + //-------------------------------------------------------------------- + case WM_CHAR: + case WM_SYSCHAR: + if(app->m_specific->m_last_translated_key == 0) + { + app->on_key(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + wParam, + app->m_specific->m_input_flags); + } + break; + + //-------------------------------------------------------------------- + case WM_PAINT: + paintDC = ::BeginPaint(hWnd, &ps); + app->m_specific->m_current_dc = paintDC; + if(app->m_specific->m_redraw_flag) + { + app->on_draw(); + app->m_specific->m_redraw_flag = false; + } + app->m_specific->display_pmap(paintDC, &app->rbuf_window()); + app->on_post_draw(paintDC); + app->m_specific->m_current_dc = 0; + ::EndPaint(hWnd, &ps); + break; + + //-------------------------------------------------------------------- + case WM_COMMAND: + break; + + //-------------------------------------------------------------------- + case WM_DESTROY: + ::PostQuitMessage(0); + break; + + //-------------------------------------------------------------------- + default: + ret = ::DefWindowProc(hWnd, msg, wParam, lParam); + break; + } + app->m_specific->m_current_dc = 0; + ::ReleaseDC(app->m_specific->m_hwnd, dc); + return ret; + } + + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + ::MessageBox(m_specific->m_hwnd, msg, "AGG Message", MB_OK); + } + + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, unsigned flags) + { + if(m_specific->m_sys_format == pix_format_undefined) + { + return false; + } + + m_window_flags = flags; + + int wflags = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; + + WNDCLASS wc; + wc.lpszClassName = "AGGAppClass"; + wc.lpfnWndProc = window_proc; + wc.style = wflags; + wc.hInstance = g_windows_instance; + wc.hIcon = LoadIcon(0, IDI_APPLICATION); + wc.hCursor = LoadCursor(0, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = "AGGAppMenu"; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + ::RegisterClass(&wc); + + wflags = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + + if(m_window_flags & window_resize) + { + wflags |= WS_THICKFRAME | WS_MAXIMIZEBOX; + } + + m_specific->m_hwnd = ::CreateWindow("AGGAppClass", + m_caption, + wflags, + 100, + 100, + width, + height, + 0, + 0, + g_windows_instance, + 0); + + if(m_specific->m_hwnd == 0) + { + return false; + } + + + RECT rct; + ::GetClientRect(m_specific->m_hwnd, &rct); + + ::MoveWindow(m_specific->m_hwnd, // handle to window + 100, // horizontal position + 100, // vertical position + width + (width - (rct.right - rct.left)), + height + (height - (rct.bottom - rct.top)), + FALSE); + + ::SetWindowLongPtr(m_specific->m_hwnd, GWLP_USERDATA, (LONG)this); + m_specific->create_pmap(width, height, &m_rbuf_window); + m_initial_width = width; + m_initial_height = height; + on_init(); + m_specific->m_redraw_flag = true; + ::ShowWindow(m_specific->m_hwnd, g_windows_cmd_show); + return true; + } + + + + //------------------------------------------------------------------------ + int platform_support::run() + { + MSG msg; + + for(;;) + { + if(m_wait_mode) + { + if(!::GetMessage(&msg, 0, 0, 0)) + { + break; + } + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + else + { + if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) + { + ::TranslateMessage(&msg); + if(msg.message == WM_QUIT) + { + break; + } + ::DispatchMessage(&msg); + } + else + { + on_idle(); + } + } + } + return (int)msg.wParam; + } + + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const { return ".bmp"; } + + + //------------------------------------------------------------------------ + const char* platform_support::full_file_name(const char* file_name) + { + return file_name; + } + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + char fn[1024]; + std::strcpy(fn, file); + int len = std::strlen(fn); + if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0) + { + std::strcat(fn, ".bmp"); + } + return m_specific->load_pmap(fn, idx, &m_rbuf_img[idx]); + } + return true; + } + + + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + char fn[1024]; + std::strcpy(fn, file); + int len = std::strlen(fn); + if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0) + { + std::strcat(fn, ".bmp"); + } + return m_specific->save_pmap(fn, idx, &m_rbuf_img[idx]); + } + return true; + } + + + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) + { + if(idx < max_images) + { + if(width == 0) width = m_specific->m_pmap_window.width(); + if(height == 0) height = m_specific->m_pmap_window.height(); + m_specific->m_pmap_img[idx].create(width, height, org_e(m_specific->m_bpp)); + m_rbuf_img[idx].attach(m_specific->m_pmap_img[idx].buf(), + m_specific->m_pmap_img[idx].width(), + m_specific->m_pmap_img[idx].height(), + m_flip_y ? + m_specific->m_pmap_img[idx].stride() : + -m_specific->m_pmap_img[idx].stride()); + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + m_specific->m_redraw_flag = true; + ::InvalidateRect(m_specific->m_hwnd, 0, FALSE); + } + + + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + HDC dc = ::GetDC(m_specific->m_hwnd); + m_specific->display_pmap(dc, &m_rbuf_window); + ::ReleaseDC(m_specific->m_hwnd, dc); + } + + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} +} + + + + +namespace agg +{ + // That's ridiculous. I have to parse the command line by myself + // because Windows doesn't provide a method of getting the command + // line arguments in a form of argc, argv. Of course, there's + // CommandLineToArgv() but first, it returns Unicode that I don't + // need to deal with, but most of all, it's not compatible with Win98. + //----------------------------------------------------------------------- + class tokenizer + { + public: + enum sep_flag + { + single, + multiple, + whole_str + }; + + struct token + { + const char* ptr; + unsigned len; + }; + + public: + tokenizer(const char* sep, + const char* trim=0, + const char* quote="\"", + char mask_chr='\\', + sep_flag sf=multiple); + + void set_str(const char* str); + token next_token(); + + private: + int check_chr(const char *str, char chr); + + private: + const char* m_src_string; + int m_start; + const char* m_sep; + const char* m_trim; + const char* m_quote; + char m_mask_chr; + unsigned m_sep_len; + sep_flag m_sep_flag; + }; + + + + //----------------------------------------------------------------------- + inline void tokenizer::set_str(const char* str) + { + m_src_string = str; + m_start = 0; + } + + + //----------------------------------------------------------------------- + inline int tokenizer::check_chr(const char *str, char chr) + { + return int(strchr(str, chr)); + } + + + //----------------------------------------------------------------------- + tokenizer::tokenizer(const char* sep, + const char* trim, + const char* quote, + char mask_chr, + sep_flag sf) : + m_src_string(0), + m_start(0), + m_sep(sep), + m_trim(trim), + m_quote(quote), + m_mask_chr(mask_chr), + m_sep_len(sep ? strlen(sep) : 0), + m_sep_flag(sep ? sf : single) + { + } + + + //----------------------------------------------------------------------- + tokenizer::token tokenizer::next_token() + { + unsigned count = 0; + char quote_chr = 0; + token tok; + + tok.ptr = 0; + tok.len = 0; + if(m_src_string == 0 || m_start == -1) return tok; + + const char *pstr = m_src_string + m_start; + + if(*pstr == 0) + { + m_start = -1; + return tok; + } + + int sep_len = 1; + if(m_sep_flag == whole_str) sep_len = m_sep_len; + + if(m_sep_flag == multiple) + { + //Pass all the separator symbols at the begin of the string + while(*pstr && check_chr(m_sep, *pstr)) + { + ++pstr; + ++m_start; + } + } + + if(*pstr == 0) + { + m_start = -1; + return tok; + } + + for(count = 0;; ++count) + { + char c = *pstr; + int found = 0; + + //We are outside of quotation: find one of separator symbols + if(quote_chr == 0) + { + if(sep_len == 1) + { + found = check_chr(m_sep, c); + } + else + { + found = std::strncmp(m_sep, pstr, m_sep_len) == 0; + } + } + + ++pstr; + + if(c == 0 || found) + { + if(m_trim) + { + while(count && + check_chr(m_trim, m_src_string[m_start])) + { + ++m_start; + --count; + } + + while(count && + check_chr(m_trim, m_src_string[m_start + count - 1])) + { + --count; + } + } + + tok.ptr = m_src_string + m_start; + tok.len = count; + + //Next time it will be the next separator character + //But we must check, whether it is NOT the end of the string. + m_start += count; + if(c) + { + m_start += sep_len; + if(m_sep_flag == multiple) + { + //Pass all the separator symbols + //after the end of the string + while(check_chr(m_sep, m_src_string[m_start])) + { + ++m_start; + } + } + } + break; + } + + //Switch quote. If it is not a quote yet, try to check any of + //quote symbols. Otherwise quote must be finished with quote_symb + if(quote_chr == 0) + { + if(check_chr(m_quote, c)) + { + quote_chr = c; + continue; + } + } + else + { + //We are inside quote: pass all the mask symbols + if(m_mask_chr && c == m_mask_chr) + { + if(*pstr) + { + ++count; + ++pstr; + } + continue; + } + if(c == quote_chr) + { + quote_chr = 0; + continue; + } + } + } + return tok; + } + + +} + + + +//---------------------------------------------------------------------------- +int agg_main(int argc, char* argv[]); + + + +//---------------------------------------------------------------------------- +int PASCAL WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + agg::g_windows_instance = hInstance; + agg::g_windows_cmd_show = nCmdShow; + + char* argv_str = new char [std::strlen(lpszCmdLine) + 3]; + char* argv_ptr = argv_str; + + char* argv[64]; + std::memset(argv, 0, sizeof(argv)); + + agg::tokenizer cmd_line(" ", "\"' ", "\"'", '\\', agg::tokenizer::multiple); + cmd_line.set_str(lpszCmdLine); + + int argc = 0; + argv[argc++] = argv_ptr; + *argv_ptr++ = 0; + + while(argc < 64) + { + agg::tokenizer::token tok = cmd_line.next_token(); + if(tok.ptr == 0) break; + if(tok.len) + { + std::memcpy(argv_ptr, tok.ptr, tok.len); + argv[argc++] = argv_ptr; + argv_ptr += tok.len; + *argv_ptr++ = 0; + } + } + + int ret = agg_main(argc, argv); + delete [] argv_str; + + return ret; +} + + + + diff --git a/src/platform/win32/agg_win32_bmp.cpp b/src/platform/win32/agg_win32_bmp.cpp new file mode 100644 index 0000000..2346b33 --- /dev/null +++ b/src/platform/win32/agg_win32_bmp.cpp @@ -0,0 +1,633 @@ +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +// Contact: mcseemagg@yahoo.com +//---------------------------------------------------------------------------- +// +// class pixel_map +// +//---------------------------------------------------------------------------- + +#include <cstring> +#include <cstdio> +#include "platform/win32/agg_win32_bmp.h" +#include "agg_basics.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + pixel_map::~pixel_map() + { + destroy(); + } + + + //------------------------------------------------------------------------ + pixel_map::pixel_map() : + m_bmp(0), + m_buf(0), + m_bpp(0), + m_is_internal(false), + m_img_size(0), + m_full_size(0) + + { + } + + + //------------------------------------------------------------------------ + void pixel_map::destroy() + { + if(m_bmp && m_is_internal) delete [] (unsigned char*)m_bmp; + m_bmp = 0; + m_is_internal = false; + m_buf = 0; + } + + + //------------------------------------------------------------------------ + void pixel_map::create(unsigned width, + unsigned height, + org_e org, + unsigned clear_val) + { + destroy(); + if(width == 0) width = 1; + if(height == 0) height = 1; + m_bpp = org; + create_from_bmp(create_bitmap_info(width, height, m_bpp)); + create_gray_scale_palette(m_bmp); + m_is_internal = true; + if(clear_val <= 255) + { + std::memset(m_buf, clear_val, m_img_size); + } + } + + + //------------------------------------------------------------------------ + HBITMAP pixel_map::create_dib_section(HDC h_dc, + unsigned width, + unsigned height, + org_e org, + unsigned clear_val) + { + destroy(); + if(width == 0) width = 1; + if(height == 0) height = 1; + m_bpp = org; + HBITMAP h_bitmap = create_dib_section_from_args(h_dc, width, height, m_bpp); + create_gray_scale_palette(m_bmp); + m_is_internal = true; + if(clear_val <= 255) + { + std::memset(m_buf, clear_val, m_img_size); + } + return h_bitmap; + } + + + + //------------------------------------------------------------------------ + void pixel_map::clear(unsigned clear_val) + { + if(m_buf) std::memset(m_buf, clear_val, m_img_size); + } + + + //------------------------------------------------------------------------ + void pixel_map::attach_to_bmp(BITMAPINFO *bmp) + { + if(bmp) + { + destroy(); + create_from_bmp(bmp); + m_is_internal = false; + } + } + + + + //static + //------------------------------------------------------------------------ + unsigned pixel_map::calc_full_size(BITMAPINFO *bmp) + { + if(bmp == 0) return 0; + + return sizeof(BITMAPINFOHEADER) + + sizeof(RGBQUAD) * calc_palette_size(bmp) + + bmp->bmiHeader.biSizeImage; + } + + //static + //------------------------------------------------------------------------ + unsigned pixel_map::calc_header_size(BITMAPINFO *bmp) + { + if(bmp == 0) return 0; + return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * calc_palette_size(bmp); + } + + + //static + //------------------------------------------------------------------------ + unsigned pixel_map::calc_palette_size(unsigned clr_used, unsigned bits_per_pixel) + { + int palette_size = 0; + + if(bits_per_pixel <= 8) + { + palette_size = clr_used; + if(palette_size == 0) + { + palette_size = 1 << bits_per_pixel; + } + } + return palette_size; + } + + //static + //------------------------------------------------------------------------ + unsigned pixel_map::calc_palette_size(BITMAPINFO *bmp) + { + if(bmp == 0) return 0; + return calc_palette_size(bmp->bmiHeader.biClrUsed, bmp->bmiHeader.biBitCount); + } + + + //static + //------------------------------------------------------------------------ + unsigned char * pixel_map::calc_img_ptr(BITMAPINFO *bmp) + { + if(bmp == 0) return 0; + return ((unsigned char*)bmp) + calc_header_size(bmp); + } + + //static + //------------------------------------------------------------------------ + BITMAPINFO* pixel_map::create_bitmap_info(unsigned width, + unsigned height, + unsigned bits_per_pixel) + { + unsigned line_len = calc_row_len(width, bits_per_pixel); + unsigned img_size = line_len * height; + unsigned rgb_size = calc_palette_size(0, bits_per_pixel) * sizeof(RGBQUAD); + unsigned full_size = sizeof(BITMAPINFOHEADER) + rgb_size + img_size; + + BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size]; + + bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmp->bmiHeader.biWidth = width; + bmp->bmiHeader.biHeight = height; + bmp->bmiHeader.biPlanes = 1; + bmp->bmiHeader.biBitCount = (unsigned short)bits_per_pixel; + bmp->bmiHeader.biCompression = 0; + bmp->bmiHeader.biSizeImage = img_size; + bmp->bmiHeader.biXPelsPerMeter = 0; + bmp->bmiHeader.biYPelsPerMeter = 0; + bmp->bmiHeader.biClrUsed = 0; + bmp->bmiHeader.biClrImportant = 0; + + return bmp; + } + + + //static + //------------------------------------------------------------------------ + void pixel_map::create_gray_scale_palette(BITMAPINFO *bmp) + { + if(bmp == 0) return; + + unsigned rgb_size = calc_palette_size(bmp); + RGBQUAD *rgb = (RGBQUAD*)(((unsigned char*)bmp) + sizeof(BITMAPINFOHEADER)); + unsigned brightness; + unsigned i; + + for(i = 0; i < rgb_size; i++) + { + brightness = (255 * i) / (rgb_size - 1); + rgb->rgbBlue = + rgb->rgbGreen = + rgb->rgbRed = (unsigned char)brightness; + rgb->rgbReserved = 0; + rgb++; + } + } + + + + //static + //------------------------------------------------------------------------ + unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel) + { + unsigned n = width; + unsigned k; + + switch(bits_per_pixel) + { + case 1: k = n; + n = n >> 3; + if(k & 7) n++; + break; + + case 4: k = n; + n = n >> 1; + if(k & 3) n++; + break; + + case 8: + break; + + case 16: n *= 2; + break; + + case 24: n *= 3; + break; + + case 32: n *= 4; + break; + + case 48: n *= 6; + break; + + case 64: n *= 8; + break; + + case 96: n *= 12; + break; + + case 128: n *= 16; + break; + + default: n = 0; + break; + } + return ((n + 3) >> 2) << 2; + } + + + + + + //------------------------------------------------------------------------ + void pixel_map::draw(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const + { + if(m_bmp == 0 || m_buf == 0) return; + + unsigned bmp_x = 0; + unsigned bmp_y = 0; + unsigned bmp_width = m_bmp->bmiHeader.biWidth; + unsigned bmp_height = m_bmp->bmiHeader.biHeight; + unsigned dvc_x = 0; + unsigned dvc_y = 0; + unsigned dvc_width = m_bmp->bmiHeader.biWidth; + unsigned dvc_height = m_bmp->bmiHeader.biHeight; + + if(bmp_rect) + { + bmp_x = bmp_rect->left; + bmp_y = bmp_rect->top; + bmp_width = bmp_rect->right - bmp_rect->left; + bmp_height = bmp_rect->bottom - bmp_rect->top; + } + + dvc_x = bmp_x; + dvc_y = bmp_y; + dvc_width = bmp_width; + dvc_height = bmp_height; + + if(device_rect) + { + dvc_x = device_rect->left; + dvc_y = device_rect->top; + dvc_width = device_rect->right - device_rect->left; + dvc_height = device_rect->bottom - device_rect->top; + } + + if(dvc_width != bmp_width || dvc_height != bmp_height) + { + ::SetStretchBltMode(h_dc, COLORONCOLOR); + ::StretchDIBits( + h_dc, // handle of device context + dvc_x, // x-coordinate of upper-left corner of source rect. + dvc_y, // y-coordinate of upper-left corner of source rect. + dvc_width, // width of source rectangle + dvc_height, // height of source rectangle + bmp_x, + bmp_y, // x, y -coordinates of upper-left corner of dest. rect. + bmp_width, // width of destination rectangle + bmp_height, // height of destination rectangle + m_buf, // address of bitmap bits + m_bmp, // address of bitmap data + DIB_RGB_COLORS, // usage + SRCCOPY // raster operation code + ); + } + else + { + ::SetDIBitsToDevice( + h_dc, // handle to device context + dvc_x, // x-coordinate of upper-left corner of + dvc_y, // y-coordinate of upper-left corner of + dvc_width, // source rectangle width + dvc_height, // source rectangle height + bmp_x, // x-coordinate of lower-left corner of + bmp_y, // y-coordinate of lower-left corner of + 0, // first scan line in array + bmp_height, // number of scan lines + m_buf, // address of array with DIB bits + m_bmp, // address of structure with bitmap info. + DIB_RGB_COLORS // RGB or palette indexes + ); + } + } + + + //------------------------------------------------------------------------ + void pixel_map::draw(HDC h_dc, int x, int y, double scale) const + { + if(m_bmp == 0 || m_buf == 0) return; + + unsigned width = unsigned(m_bmp->bmiHeader.biWidth * scale); + unsigned height = unsigned(m_bmp->bmiHeader.biHeight * scale); + RECT rect; + rect.left = x; + rect.top = y; + rect.right = x + width; + rect.bottom = y + height; + draw(h_dc, &rect); + } + + + + + //------------------------------------------------------------------------ + void pixel_map::blend(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const + { +#if !defined(AGG_BMP_ALPHA_BLEND) + draw(h_dc, device_rect, bmp_rect); + return; +#else + if(m_bpp != 32) + { + draw(h_dc, device_rect, bmp_rect); + return; + } + + if(m_bmp == 0 || m_buf == 0) return; + + unsigned bmp_x = 0; + unsigned bmp_y = 0; + unsigned bmp_width = m_bmp->bmiHeader.biWidth; + unsigned bmp_height = m_bmp->bmiHeader.biHeight; + unsigned dvc_x = 0; + unsigned dvc_y = 0; + unsigned dvc_width = m_bmp->bmiHeader.biWidth; + unsigned dvc_height = m_bmp->bmiHeader.biHeight; + + if(bmp_rect) + { + bmp_x = bmp_rect->left; + bmp_y = bmp_rect->top; + bmp_width = bmp_rect->right - bmp_rect->left; + bmp_height = bmp_rect->bottom - bmp_rect->top; + } + + dvc_x = bmp_x; + dvc_y = bmp_y; + dvc_width = bmp_width; + dvc_height = bmp_height; + + if(device_rect) + { + dvc_x = device_rect->left; + dvc_y = device_rect->top; + dvc_width = device_rect->right - device_rect->left; + dvc_height = device_rect->bottom - device_rect->top; + } + + HDC mem_dc = ::CreateCompatibleDC(h_dc); + void* buf = 0; + HBITMAP bmp = ::CreateDIBSection( + mem_dc, + m_bmp, + DIB_RGB_COLORS, + &buf, + 0, + 0 + ); + memcpy(buf, m_buf, m_bmp->bmiHeader.biSizeImage); + + HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp); + + BLENDFUNCTION blend; + blend.BlendOp = AC_SRC_OVER; + blend.BlendFlags = 0; + +#if defined(AC_SRC_ALPHA) + blend.AlphaFormat = AC_SRC_ALPHA; +//#elif defined(AC_SRC_NO_PREMULT_ALPHA) +// blend.AlphaFormat = AC_SRC_NO_PREMULT_ALPHA; +#else +#error "No appropriate constant for alpha format. Check version of wingdi.h, There must be AC_SRC_ALPHA or AC_SRC_NO_PREMULT_ALPHA" +#endif + + blend.SourceConstantAlpha = 255; + ::AlphaBlend( + h_dc, + dvc_x, + dvc_y, + dvc_width, + dvc_height, + mem_dc, + bmp_x, + bmp_y, + bmp_width, + bmp_height, + blend + ); + + ::SelectObject(mem_dc, temp); + ::DeleteObject(bmp); + ::DeleteObject(mem_dc); +#endif //defined(AGG_BMP_ALPHA_BLEND) + } + + + //------------------------------------------------------------------------ + void pixel_map::blend(HDC h_dc, int x, int y, double scale) const + { + if(m_bmp == 0 || m_buf == 0) return; + unsigned width = unsigned(m_bmp->bmiHeader.biWidth * scale); + unsigned height = unsigned(m_bmp->bmiHeader.biHeight * scale); + RECT rect; + rect.left = x; + rect.top = y; + rect.right = x + width; + rect.bottom = y + height; + blend(h_dc, &rect); + } + + + //------------------------------------------------------------------------ + bool pixel_map::load_from_bmp(FILE *fd) + { + BITMAPFILEHEADER bmf; + BITMAPINFO *bmi = 0; + unsigned bmp_size; + + if (std::fread(&bmf, sizeof(bmf), 1, fd) != 1) goto bmperr; + if(bmf.bfType != 0x4D42) goto bmperr; + + bmp_size = bmf.bfSize - sizeof(BITMAPFILEHEADER); + + bmi = (BITMAPINFO*) new unsigned char [bmp_size]; + if(std::fread(bmi, 1, bmp_size, fd) != bmp_size) goto bmperr; + destroy(); + m_bpp = bmi->bmiHeader.biBitCount; + create_from_bmp(bmi); + m_is_internal = 1; + return true; + + bmperr: + if(bmi) delete [] (unsigned char*) bmi; + return false; + } + + + + //------------------------------------------------------------------------ + bool pixel_map::load_from_bmp(const char *filename) + { + FILE *fd = std::fopen(filename, "rb"); + bool ret = false; + if(fd) + { + ret = load_from_bmp(fd); + std::fclose(fd); + } + return ret; + } + + + + //------------------------------------------------------------------------ + bool pixel_map::save_as_bmp(FILE *fd) const + { + if(m_bmp == 0) return 0; + + BITMAPFILEHEADER bmf; + + bmf.bfType = 0x4D42; + bmf.bfOffBits = calc_header_size(m_bmp) + sizeof(bmf); + bmf.bfSize = bmf.bfOffBits + m_img_size; + bmf.bfReserved1 = 0; + bmf.bfReserved2 = 0; + + std::fwrite(&bmf, sizeof(bmf), 1, fd); + std::fwrite(m_bmp, m_full_size, 1, fd); + return true; + } + + + + //------------------------------------------------------------------------ + bool pixel_map::save_as_bmp(const char *filename) const + { + FILE *fd = std::fopen(filename, "wb"); + bool ret = false; + if(fd) + { + ret = save_as_bmp(fd); + std::fclose(fd); + } + return ret; + } + + + //------------------------------------------------------------------------ + unsigned char* pixel_map::buf() + { + return m_buf; + } + + //------------------------------------------------------------------------ + unsigned pixel_map::width() const + { + return m_bmp->bmiHeader.biWidth; + } + + //------------------------------------------------------------------------ + unsigned pixel_map::height() const + { + return m_bmp->bmiHeader.biHeight; + } + + //------------------------------------------------------------------------ + int pixel_map::stride() const + { + return calc_row_len(m_bmp->bmiHeader.biWidth, + m_bmp->bmiHeader.biBitCount); + } + + + //private + //------------------------------------------------------------------------ + void pixel_map::create_from_bmp(BITMAPINFO *bmp) + { + if(bmp) + { + m_img_size = calc_row_len(bmp->bmiHeader.biWidth, + bmp->bmiHeader.biBitCount) * + bmp->bmiHeader.biHeight; + + m_full_size = calc_full_size(bmp); + m_bmp = bmp; + m_buf = calc_img_ptr(bmp); + } + } + + + //private + //------------------------------------------------------------------------ + HBITMAP pixel_map::create_dib_section_from_args(HDC h_dc, + unsigned width, + unsigned height, + unsigned bits_per_pixel) + { + unsigned line_len = calc_row_len(width, bits_per_pixel); + unsigned img_size = line_len * height; + unsigned rgb_size = calc_palette_size(0, bits_per_pixel) * sizeof(RGBQUAD); + unsigned full_size = sizeof(BITMAPINFOHEADER) + rgb_size; + + BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size]; + + bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmp->bmiHeader.biWidth = width; + bmp->bmiHeader.biHeight = height; + bmp->bmiHeader.biPlanes = 1; + bmp->bmiHeader.biBitCount = (unsigned short)bits_per_pixel; + bmp->bmiHeader.biCompression = 0; + bmp->bmiHeader.biSizeImage = img_size; + bmp->bmiHeader.biXPelsPerMeter = 0; + bmp->bmiHeader.biYPelsPerMeter = 0; + bmp->bmiHeader.biClrUsed = 0; + bmp->bmiHeader.biClrImportant = 0; + + void* img_ptr = 0; + HBITMAP h_bitmap = ::CreateDIBSection(h_dc, bmp, DIB_RGB_COLORS, &img_ptr, NULL, 0); + + if(img_ptr) + { + m_img_size = calc_row_len(width, bits_per_pixel) * height; + m_full_size = 0; + m_bmp = bmp; + m_buf = (unsigned char *) img_ptr; + } + + return h_bitmap; + } +} + + +